1、否则将第二个有序表中的元素aj复制到rk中,并令j和k分别加上1,如此循环下去,直到其中一个有序表取完,然后再将另一个有序表中剩余的元素复制到r中从下标k到下标t的单元。归并排序的算法我们通常用递归实现,先把待排序区间s,t以中点二分,接着把左边子区间排序,再把右边子区间排序,最后把左区间和右区间用一次归并操作合并成有序的区间s,t。实现时间计量:#define _CLOCK_T_DEFINEDsrand(unsigned)time(0);/定义一数组an;对每一个赋予一值。ai=rand();得到随即数。duration =(double)(finish -start)/CLOCKS_PER
2、_SEC;start=clock();将系统时间赋予Start。以便以后进行比较。std:sort(b,b+1000);系统执行1000个数据。Finish-Start为最终结果。五、实验结果与数据处理实验结果截图:实验代码:#includealgorithmtime.hstdio.hstdlib.husing namespace std;templatevoid MergSort(Type a, int n) Type *b = new Typen; int s = 1; while (s n) MergPass(a, b, s, n); s += s; MergPass(b, a, s,
3、n); void MergPass(Type x, Type y, int s, int n) int i = 0; while (i = n - 2 * s) Merg(x, y, i, i + s - 1, i + 2 * s - 1); i = i + 2 * s; if (i + s n) Merg(x, y, i, i + s - 1, n - 1); else for (int j = i; j = n - 1; j+) yj = xj; void Merg(Type c, Type d, int l, int m, int r) int i = l, j = m + 1, k =
4、 l; while (i = m) & (j = r) if (ci m) for (int q = j; q = r; q+) dk+ = cq; else for (int q = i;= m;float randf(float base, float up) return (rand() % (int)(up - base) * RAND_MAX)/(float)RAND_MAX ; /产生随机数void printArray(float *a,int N) for(int i=0;i0) coutaiendl; else ;void main() int ArrayLen = 5; c
5、outArrayLen; float *array = new floatArrayLen; float *arrays = new floatArrayLen; float mn, ene; printf(数组已建立: n); srand(unsigned)time(NULL); /设置随机数的seed for (int i = 0; i ArrayLen; i+) mn = (float)rand(); /产生小数 ene = randf(1,10000)+mn; arraysi =ene; arrayi = ene; /cout需要排序的归并数组:n /printArray(array,
6、 ArrayLen); int flag = 1; while (flag != 0)n输入需要显示的排序方法: cout 1.归并排序 2.std排序 0.退出 flag; switch (flag) case 0: break; case 1: clock_t s = 0, e = 0; s = clock(); MergSort(array, ArrayLen); e = clock();排序后的序列为: cout nMergSort运行了: (e - s) ms case 2: clock_t start1 = 0, end1 = 0; start1 = clock(); std:so
7、rt(&arrays0, &arraysArrayLen); end1 = clock(); /printArray(array, ArrayLen);nstd:sort运行了: (end1 - start1) sFileName = sFileName1; ifstream fin(sFileName); char ch4; fin.getline(ch, 4); int n1 = atoi(ch); cout 节点数目:n1 n = n1;t = new THaffmanNode2 * n1 - 1;nNext = n1; char ch1; in1; fin.get(ch1); ti.c
8、 = ch1; fin.ignore(100, , fin.getline(ch, 4); ti.f = atoi(ch);n; ti.c ti.f = 2) THaffmanNode nn, nr, nl; nl = PQ.top(); PQ.pop(); nr = PQ.top(); nn.f = nl.f + nr.f; nn.l = nl.idx; nn.r = nr.idx; nn.idx = nNext+; tnl.idx.p = nn.idx; tnr.idx.p = nn.idx; tnn.idx = nn; PQ.push(nn); t2 * n - 2.p = -1;Huf
9、fman(void)void Huffman:OutputTree()2 * n - 1;权重:左孩子: ti.l 右孩子: ti.r 父节点: ti.p 在数组的位置: ti.idx /现在数组中存的是哈弗曼数OutputCode() /用stack 来依次记录各编码的0 1 编码stackint, std:list sk; THaffmanNode ntemp, ntemp1; ntemp = ti; while (ntemp.p != -1) ntemp1 = tntemp.p; if (tntemp1.l.idx = ntemp.idx) sk.push(0); ntemp = nte
10、mp1; else sk.push(1); int i1 = sk.size(); : for (int i = 0;i1; sk.top(); sk.pop();综合实验三 用回溯方法求解n后问题问题:对任意给定的n求解n后问题。具体要求:1封装n后问题为类,编写以下两种算法进行求解:(1)递归回溯方法;(2)迭代回溯方法。(选)2对任意给定的n,要求输出其解向量(所有解),并输出其解数;3构造n后问题的解数表格(由程序自动生成):n 后数解数第一个解42(2,4,1,3)56回溯原理:回溯算法也叫试探法,它是一种系统地搜索问题的解的方法。回溯算法的基本思想是:从一条路往前走,能进则进,不能
11、进则退回来,换一条路再试。用回溯算法解决问题的一般步骤为:1、定义一个解空间,它包含问题的解。2、利用适于搜索的方法组织解空间。3、利用深度优先法搜索解空间。4、利用限界函数避免移动到不可能产生解的子空间。问题的解空间通常是在搜索问题的解的过程中动态产生的,这是回溯算法的一个重要特性。n后问题等于在nn格的棋盘上放置n个皇后,任何2个皇后不放在同一行或同一列或同一斜线上。即规定每一列放一个皇后,不会造成列上的冲突;当第i行被某个皇后占领后,则同一行上的所有空格都不能再放皇后,要把以i为下标的标记置为被占领状态。K:第K个皇后,也表示第K行Xi:第K个皇后在第K行的 第i列皇后k在第k行第xk列
12、时,xi=xk时,两皇后在同一列上;abs(xi-xk)=abs(i-k)时,两皇后在同一斜线上;两种情况两皇后都可相互攻击,返回false表示不符合条件。math.hclass Queenfriend int nQueen(int);private: bool Place(int k); void Backtrack(int t); int n,*x; /当前解 long sum; /当前已找到的可行方案数;bool Queen:Place(int k) for (int j=1;jn) sum+;/达到叶结点 for(int i=1;=n;i+)xi for(i=1;+i) for(int
13、 j=1;+j) if(xi!=j) cout. ;# for (int i=1;i+) /搜索子结点 xt=i; /进入第i个子结点 if (Place(t) Backtrack(t+1);int nQueen(int n)Queen X;/初始化XX.n=n;X.sum=0;int *p=new int n+1;for(int i=0; pi=0;X.x=p;X.Backtrack(1); /对整个解空间回溯搜索delete p;return X.sum;void main() int a=0,b=0;*欢迎进入皇后问题* int flag=1; while(flag)请输入皇后数a; b
14、=nQueen(a);方案个数:b是否继续?1为是,0为否flag;综合实验四 背包问题的贪心算法问题:给定如下n种物品的编号,及其价值;背包重量为c, 求最佳装包方案,才能使其装入背包的价值最大。物品编号1n重量w1w2.wn价值v1v2vn将背包问题进行类的封装;能对任意给定的n种物品的重量、价值及背包限重,输出以上表格( 或纵向输出);输出背包问题的解;本题要求采用STL库中的排序算法数据进行排序。贪心算法解决背包问题有几种策略:(1)一种贪心准则为:从剩余的物品中,选出可以装入背包的价值最大的物品,利用这种规则,价值最大的物品首先被装入(假设有足够容量),然后是下一个价值最大的物品,如
15、此继续下去。这种策略不能保证得到最优解。例如,考虑n=2, w=100,10,10, p =20,15,15, c = 105。当利用价值贪婪准则时,获得的解为x= 1 , 0 , 0 ,这种方案的总价值为2 0。而最优解为 0 , 1 , 1 ,其总价值为3 0。(2)另一种方案是重量贪心准则是:从剩下的物品中选择可装入背包的重量最小的物品。虽然这种规则对于前面的例子能产生最优解,但在一般情况下则不一定能得到最优解。考虑n= 2 ,w=10,20, p=5,100, c= 2 5。当利用重量贪婪策略时,获得的解为x =1,0,比最优解 0 , 1 要差。(3)还有一种贪心准则,就是我们教材上
16、提到的,认为,每一项计算yi=vi/si,即该项值和大小的比,再按比值的降序来排序,从第一项开始装背包,然后是第二项,依次类推,尽可能的多放,直到装满背包。首先计算每种物品单位重量的价值Vi/Wi,然后依贪心选择策略,将尽可能多的单位重量价值最高的物品装入背包。若将这种物品全部装入背包后,背包内的物品总重量未超出C,则选择单位重量价值次高的物品,并尽可能多的装入背包。依此策略一直进行下去,直到背包装满为止。采用贪婪准则:每次选择p/w最大的物品放入背包。注意在这之前的计算每种物品单位重量的价值Vi/Wi后,进行排序。实验截图:#include #define M 4 struct node float no;/编号 fl
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1