算法设计与分析所有程序文件37213.pdf





《算法设计与分析所有程序文件37213.pdf》由会员分享,可在线阅读,更多相关《算法设计与分析所有程序文件37213.pdf(68页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、目 录 第二章 递归与分治.3 1、用递归思想求 N!.3 2、用递归思想求 Fibonacci 数列.3 3、用递归思想求排列问题.4 4、用递归思想求整数划分问题.5 5、用递归思想求汉诺塔问题.6 6、用递归思想实现插入排序.7 7、用分治思想实现二分查找.8 8、用分治法求两个大整数的乘法.9 9、用分治思想求一个数组的最大值与最小值.10 10、用分法思想实现合并排序.12 11、用分治思想实现快速排序.13 12、用分治法实现线性时间选择问题.15 13、用分法思想实现残缺棋盘问题.15 第三章 动态规划法.18 1、矩阵连乘问题.18 2、最长公子序列.20 3、最大子段和问题.
2、23 4、图像压缩问题.28 5、电路布线问题.31 6、最.31 7、最.31 第四章 贪心算法.32 1、哈夫曼编码.32 4、Kruskal 算法求最小生成树.35 5、集装箱问题.38 6、活动安排问题.40 第五章 回溯法.42 1、用回溯法求 01 背包问题.42 2、用回溯法求 N 皇后问题.45 3、用回溯法求旅行售货员问题.46 4、用回溯法求圆排列问题.48 5、用回溯法求符号三角形问题.50 6、用回溯法求批处理作业调度问题.52 7、用回溯法求连续邮资问题.54 8、用回溯法求图的 m 着色问题.57 9、用回溯法求最大团问题.59 第六章 回溯法.62 1、用分支限界
3、法求 01 背包问题.62 第二章 递归与分治 1、用递归思想求 N!王晓东版计算机算法设计与分析(第四版)P11 页,例 21#include void main()long n;int JieChen(int n);printf(请输入一个数n);scanf(%ld,&n);long result=JieChen(n);printf(%ld,result);int JieChen(int n)if(n=1)return 1;else return n*JieChen(n-1);2、用递归思想求 Fibonacci 数列 王晓东版计算机算法设计与分析(第四版)P12 页,例 22 int F
4、ibonacci(int n)if(n=1)return 1;else return Fibonacci(n-1)+Fibonacci(n-2);void main()long n;printf(请输入一个数n);scanf(%ld,&n);long result=Fibonacci(n);printf(%ldn,result);3、用递归思想求排列问题 王晓东版计算机算法设计与分析(第四版)P13 页,例 24 N 个元素的全排列的个数为:N!本算法非常重要,因为它是很多算法的基础,比如回溯法那章里的算法很多都是以本算法为基础的。#include /交换两个元素的值 void Swap(in
5、t&x,int&y)int t=x;x=y;y=t;/产生 listk:m的所有排列/m 是最后一个元素在数组中的下标 void Perm(int list,int k,int m)if(k=m)/如果只有一个元素 for(int i=0;i=m;i+)printf(%d,listi);printf(n);else for(int i=k;i=m;i+)Swap(listi,listk);Perm(list,k+1,m);Swap(listi,listk);/将元素还原 void main()int a5=1,2,3,4,5;/求数组前面三个元素的全排列 Perm(a,0,3);4、用递归思想
6、求整数划分问题 王晓东版计算机算法设计与分析(第四版)P14 页,例 25 整数划分问题是算法中的一个经典命题之一,有关这个问题的讲述在讲解到递归时基本都将涉及。所谓整数划分,是指把一个正整数 n 写成如下形式:n=m1+m2+mi;(其中 mi 为正整数,并且 1=mi=n),则m1,m2,.,mi为 n 的一个划分。如果m1,m2,.,mi中的最大值不超过 m,即 max(m1,m2,.,mi)0),只有一种划分即1;(2)当 m=1 时,不论 n 的值为多少,只有一种划分即 n 个 1,1,1,1,.,1;(3)当 n=m 时,根据划分中是否包含 n,可以分为两种情况:(a).划分中包含
7、 n 的情况,只有一个即 n;(b).划分中不包含 n 的情况,这时划分中最大的数字也一定比 n 小,即 n 的所有(n-1)划分。因此 f(n,n)=1+f(n,n-1);(4)当 n m 时,根据划分中是否包含最大值 m,可以分为两种情况:(a).划分中包含 m 的情况,即m,x1,x2,.,xi,其中x1,x2,.,xi 的和为 n-m,可能再次出现 m,因此是(n-m)的 m 划分,因此这种划分个数为 f(n-m,m);(b).划分中不包含 m 的情况,则划分中所有值都比 m 小,即 n 的(m-1)划分个数为f(n,m-1);因此 f(n,m)=f(n-m,m)+f(n,m-1);综
8、合以上情况,我们可以看出,上面的结论具有递归定义特征,其中(1)和(2)属于回归条件,(3)和(4)属于特殊情况,将会转换为情况(5)。而情况(5)为通用情况,属于递推的方法,其本质主要是通过减小 m 以达到回归条件,从而解决问题。其递推表达式如下:f(n,m)=1;(n=1 or m=1)f(n,m)=f(n,n);(n m)因此我们可以给出求出 f(n,m)的递归函数代码如下。/求整数 n 的全部划分数,其中 max 代表最大加数 long GetPartitionCount(int n,int max)if(n=1|max=1)return 1;else if(n 0)Hanoi(n-1
9、,A,C,B);printf(%d,%c-%cn,n,A,B);/模拟移动过程 Hanoi(n-1,C,B,A);void main()Hanoi(3,a,b,c);6、用递归思想实现插入排序#include#include#include void insertSort(int*aa,int n)if(n0)n=n-1;insertSort(aa,n);int a=aan;int k=n-1;while(k=0)&aaak)aak+1=aak;k-;aak+1=a;void main()int a10;srand(unsigned int)time(NULL);for(int i=0;i10
10、;i+)ai=rand()%100;printf(%d,ai);printf(n);insertSort(a,10);for(i=0;iright)return-1;if(x=amiddle)return middle;else if(xamiddle)return BinarySearch(a,x,middle+1,right);else return BinarySearch(a,x,left,middle-1);void main()int a9=-2,2,7,9,19,21,34,65,98;int index=BinarySearch(a,100,8);printf(%dn,inde
11、x);方法二:用循环代替递归/在 a 数组里查找是否存在 x 这个元素,如果存在,则返回元素所在下标,如果不存在/则返回-1/n 为最后一个元素的下标 int BinarySearch(int a,int x,int n)int left=0;/开始需要查找元素的下标 int right=n-1;/最后需要查找元素的下标 while(leftamiddle)left=middle+1;else right=middle-1;return-1;8、用分治法求两个大整数的乘法 最简单的方法,这里没有体现分治法的思想#include int main()char a100,b100,s202;int
12、 i,j,g,t=0,k=0,temp;printf(请输入两个大整数,空格分隔n);scanf(%s%s,&a,&b);int m=strlen(a);int n=strlen(b);while(km+n-2)sk=0;temp=0;for(i=0;im;i+)for(j=0;jn;j+)if(i+j)=k)/第 k 位上所有数字之和 temp+=(am-1-i-48)*(bn-1-j-48);g=(temp+t)%10;t=(temp+t)/10;/t 用来保存进位 sk=g;k+;/求最高 1 位或者 2 位,并输出 temp=0;for(i=0;im;i+)for(j=0;j=0;i-
13、)printf(%d,si);printf(n);return 0;9、用分治思想求一个数组的最大值与最小值#include#include#include#define LEN 8 void maxmin(int a,int*max,int*min,int low,int high)int mid,max1,min1,max2,min2;if(high-low)=alow)*max=ahigh;*min=alow;else *max=alow;*min=ahigh;else mid=(high+low)/2;maxmin(a,&max1,&min1,low,mid);maxmin(a,&ma
14、x2,&min2,mid+1,high);*max=max1max2?max1:max2;*min=min1min2?min1:min2;void main()int aLEN;int max=-1,min=1000;srand(unsigned)time(NULL);printf(数组里的元素为:n);for(int i=0;iLEN;i+)ai=rand()%100;printf(%d,ai);maxmin(a,&max,&min,0,LEN-1);printf(n 最大值为:%d n 最小值为:%dn,max,min);#include#include#include#define LE
15、N 8 void main()int aLEN;srand(unsigned)time(NULL);printf(数组里的元素为:n);for(int i=0;iLEN;i+)ai=rand()%100;printf(%d,ai);*/10、用分法思想实现合并排序#include int b9;void merge(int c,int d,int l,int m,int r)int i=l,j=m+1,k=l;while(i=m)&(j=r)if(ci=cj)dk+=ci+;else dk+=cj+;/将剩余部分处理好 while(j=r)dk+=cj+;while(i=m)dk+=ci+;v
16、oid mergesort(int a,int left,int right)if(leftright)int i=(left+right)/2;mergesort(a,left,i);/将左边部分排好序 mergesort(a,i+1,right);/将右边部分排好序 merge(a,b,left,i,right);/将左右两边合并 for(int j=left;j=right;j+)aj=bj;void main()int a9=4,3,6,8,9,1,25,2,34;printf(原始数据为:n);for(int i=0;i9;i+)printf(%dt,ai);mergesort(a,
17、0,8);printf(n 合并后的数据为:n);for(i=0;i9;i+)printf(%dt,ai);printf(n);11、用分治思想实现快速排序#include void quicksort(int a,int p,int r)int partition(int a,int p,int r);if(pr)/不止一个元素时 int q=partition(a,p,r);quicksort(a,p,q-1);quicksort(a,q+1,r);/以 ap为基准,将数组 ap-ar段元素分为两部,其实一部分/比 ap小,另一部分比 ap大,/返回值为 ap最终所在位置 int part
18、ition(int a,int p,int r)void swap(int*x,int*y);int i=p,j=r+1;int x=ap;while(true)while(a+ix&ix&jp);if(i=j)break;swap(&ai,&aj);ap=aj;aj=x;return j;void swap(int*x,int*y)int t;t=*x;*x=*y;*y=t;void main()int a9=9,8,7,6,5,4,3,2,1;printf(n 排序前的结果n);for(int i=0;i9;i+)printf(%dt,ai);quicksort(a,0,8);printf
19、(n 排序后的结果n);for(i=0;i9;i+)printf(%dt,ai);printf(n);如果每次划分不以 ap为基准,而是随机从 ap-ar里取一个数为基准,则可以设计如下随机化快速排序算法。/随机选择策略的划分算法,需要调用 partition 函数 int RandomizedPartition(int a,int p,int r)srand(unsigned int)time(NULL);int i=p+rand()%(r-p+1);swap(&ai,&ap);return partition(a,p,r);12、用分治法实现线性时间选择问题 本算法要用到上面快速排序的随机
20、划分算法 int RandomizedSelect(int a,int p,int r,int k)if(p=r)/如果只剩下一个数,则这个肯定就是第 k 小的数 return ap;else int i=RandomizedPartition(a,p,r);/经过快速排序进行划分 int j=i-p+1;/计算通过划分后,从 ap到 ai有多少数 if(k=j)/第 k 小的数在 ai的前半段 return RandomizedSelect(a,p,i,k);else/第 k 小的数在 ai的后半段,并且从 ap到 ai这些数都小于第 k 小的数 return RandomizedSelec
21、t(a,i+1,r,k-j);13、用分法思想实现残缺棋盘问题 王晓东版计算机算法设计与分析(第四版)P20 页,例 2.6 注意:同一种形状的骨牌,在填充时数字不一样,关键看三个相同数字摆放位置所构成的形状。#include int tile=1;/L 型骨牌的编号(递增)int board100100;/棋盘/*tr-当前棋盘左上角的行号*tc-当前棋盘左上角的列号*dr-当前特殊方格所在的行号*dc-当前特殊方格所在的列号*size:当前棋盘的:2k*/void chessBoard(int tr,int tc,int dr,int dc,int size)if(size=1)/棋盘方格
22、大小为 1,说明递归到最里层 return;int t=tile+;/每次递增 1 int s=size/2;/棋盘中间的行、列号(相等的)/检查特殊方块是否在左上角子棋盘中 if(drtr+s&dctc+s)/在 chessBoard(tr,tc,dr,dc,s);else /不在,将该子棋盘右下角的方块视为特殊方块 boardtr+s-1tc+s-1=t;chessBoard(tr,tc,tr+s-1,tc+s-1,s);if(dr=tc+s)/在 chessBoard(tr,tc+s,dr,dc,s);else /不在,将该子棋盘左下角的方块视为特殊方块 boardtr+s-1tc+s=
23、t;chessBoard(tr,tc+s,tr+s-1,tc+s,s);/检查特殊方块是否在左下角子棋盘中 if(dr=tr+s&dc=tr+s&dc=tc+s)chessBoard(tr+s,tc+s,dr,dc,s);else boardtr+stc+s=t;chessBoard(tr+s,tc+s,tr+s,tc+s,s);void main()int size;printf(输入棋盘的 size,大小必须是 2 的 n 次幂:);scanf(%d,&size);int index_x,index_y;printf(输入特殊方格位置的坐标:);scanf(%d%d,&index_x,&i
24、ndex_y);chessBoard(0,0,index_x,index_y,size);for(int i=0;isize;i+)for(int j=0;jsize;j+)printf(%dt,boardij);printf(n);第三章 动态规划法 1、矩阵连乘问题#include#include /n 矩阵的个数/p 记录各矩阵的维数,n 个矩阵有 n+1 个维数,Ai 的维数为 pi-1,pi/mij 记录从第 i 个矩阵到第 j 个矩阵连乘,最小的数乘次数/sij 记录从第 i 个矩阵到第 j 个矩阵连乘,取最小的数乘次数时,最后两个矩阵相乘时的位置/如果 sij=k,则代表从第 i
25、 个矩阵到第 k 个矩阵连乘,得到一个结果矩阵,/从第 k+1 个矩阵到第 j 个矩阵连乘,得到另一个结果矩阵,然后这两个结果矩阵做最后的乘法 void MatrixChain(int*p,int n,int(*m)7,int(*s)7)for(int i=1;i=n;i+)mii=0;for(int len=2;len=n;len+)/遍历矩阵链的长度 /当矩阵链的长度的长度固定为 len 时,这时有 n-len+1 个矩阵链需要求最小数乘 /下面的循环用来从前往后求这 n-len+1 个矩阵链的最小数乘值 for(int i=1;i=n-len+1;i+)/求从第 i 个矩阵到第 i+le
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 算法 设计 分析 所有 程序 文件 37213

限制150内