1、 int key;RecType;四.功能模块详细设计4.1 详细设计思想主函数:#includestdlib.h#include #define L 8 /排序元素个数#define FALSE 0#define TRUE 1RecType RL;int num;int sum;int sun; /定义排序趟数的全局变量 /系统主界面/主函数int main() RecType S100; int i,k; char ch1,ch2,q; printf(ntt*排序算法演示系统*nntt请输入%d个待排序的数据:n,L); for(i=1;i=L;i+) printf(tt请输入第%dth数
2、据:,i); scanf(%d,&Si.key); getchar(); ch1=y; while(ch1=) ntt 菜 单 n);ntt*nntt * 1-更新排序数据* 2-直接插入排序 nntt * 3-希 尔 排 序* 4-冒 泡 排 序 nntt * 5-快 速 排 序* 6-直接选择排序 nntt * 7-堆 排 序 * 8-归 并 排 序 nntt *0-退 出* nntt*nntt请选择:%cch2); for(i=1; Ri.key=Si.key; switch(ch2) case 1: printf(ntt请输入%d个待排序数据ntt for(i=1; scanf( ge
3、tchar(); printf(tt ntt数据输入完毕! break;2 Insertsort();3 Shellsort();4 Bubblesort();5ntt原始数据为(按回车键开始排序):ntt for(k=1;kk+)%5d,Rk.key); getchar(); num=0;sun=0;sum=0; Quicksort(1,L);ntt排序最终结果是:ntt比较次数是:%dntt,sum);ntt交换次数是:,sun);6 Selectsort();7 Heap();8 Mergesort();0 ch1=n default: system(cls/清屏ntt对不起,您输入有误
4、,请重新输入! if(ch2!= if(ch2=|ch2=nntt排序完毕!ntt按回车键继续! q=getchar(); if(q!n getchar(); ch1= return 1;图一 主界面4.1.1 冒泡排序核心思想 依次比较相邻的两个数,将小数放在前面,大数放在后面,第一轮比较后,最大的数便被放到了最后;第二轮操作前n-1个数据(假设有n个数据),依然是依次比较相邻的两个数,将小数放在前面,大数放在后面,倒数第二个数便是第二大的数;同理第i轮操作前n-i+1的数据(假设i取值是从1开始的),则n-i+i位置上的数据为第i大的数据。一共有n-1轮,第i轮比较中共比较n-i次比较。核
5、心代码void Bubblesort() int i,j,k,x=0,y=0,m=0; int exchange=TRUE;/标志位exchange初始化为TRUE 1 for(k=1; getchar();L&exchange=TRUE;i+)/外层对总的循环次数执行次数 exchange=FALSE; for(j=1;j=L+1-i;j+) /内层相邻记录的交换与比较 m+;/比较次数+ if(Rj.keyRj-1.key) R0.key=Rj.key; Rj.key=Rj-1.key; Rj-1.key=R0.key; exchange=TRUE; y+;/移动次数+ m-;/比较次数
6、if(exchange) /输出语句tt第%d趟冒泡排序的结果为: printf(,m);ntt移动次数是:,y); printf(,Ri.key);图二 直接插入排序4.1.2 快速排序 首先检查数据列表中的数据数,如果小于两个,则直接退出程序。如果有超过两个以上的数据,就选择一个分割点将数据分成两个部分,小于分割点的数据放在一组,其余的放在另一组,然后分别对两组数据排序。 通常分割点的数据是随机选取的。这样无论你的数据是否已被排列过,你所分割成的两个字列表的大小是差不多的。而只要两个子列表的大小差不多/递归算法实现void Quicksort(int low,int high) int i
7、=low,j=high,k; R0.key=Rlow.key; while(ij) while(ij&R0.key=Rj.key) /右侧扫描 j-; sum+; if(i Ri.key=Rj.key;/交换 i+; sun+;Ri.keyR0.key)/左侧扫描 i+; Rj.key=Ri.key; j-; sun+; Ri.key=R0.key; num+; /输出语句包括排序的结果及次数 tt第%d趟快速排序的结果为:,num); if(lowi-1) Quicksort(low,i-1);/递归部分(左侧) if(j+1high) Quicksort(j+1,high);/递归部分(右
8、侧) 图三 快速排序4.1.3 直接插入排序经过i-1遍处理后,L1.i-1己排好序。第i遍处理仅将Li插入L1.i-1的适当位置,使得L1.i又是排好序的序列。要达到这个目的,我们可以用顺序比较的方法。首先比较Li和Li-1,如果Li-1 Li,则L1.i已排好序,第i遍处理就结束了;否则交换Li与Li-1的位置,继续比较Li-1和Li-2,直到找到某一个位置j(1ji-1),使得Lj Lj+1时为止void Insertsort() int i,j,k,m=0,x=0; /初始化比较次数变量m,移动次数变量xntt原始数据为:(按回车键开始排序)ntt /主要运行部分 for(i=2; i
9、f(Ri.keyRi-1.key) R0=Ri; j=i-1; while(R0.keyRj.key) Rj+1=Rj; j-; Rj+1=R0; x+; m+; /输出语句包括排序的结果及次数 tt第%d趟直接插入排序的结果为: for(k=1; printf(,x);图四 直接插入排序4.1.4 希尔排序 先取一个小于n的整数d1作为第一个增量,把文件的全部记录分成d1个组。所有距离为dl的倍数的记录放在同一个组中。先在各组内进行直接插入排序;然后,取第二个增量d2d1重复上述的分组和排序,直至所取的增量dt=1(dtdt-ld20) for(i=gap+1; j=i-gap; while
10、(j if(Rj.keyRj+gap.key) x=Rj.key;/交换语句 Rj.key=Rj+gap.key; Rj+gap.key=x; j=j-gap; y+; else j=0; gap=gap/2;tt第%d趟希尔排序的结果为:图五 希尔排序4.1.5 直接选择排序 第一次从R0Rn-1中选取最小值,与R0交换,第二次从R1Rn-1中选取最小值,与R2交换,., 第i次从Ri-1Rn-1中选取最小值,与Ri-1交换,.,第n-1次从Rn-2Rn-1中选取最小值,与Rn-2交换,总共通过n-1次,得到一个按排序码从小到大排列的有序序列.void Selectsort() int i,
11、j,k,h,x=0,y=0;L; h=i; for(j=i+1;j+) x+; /比较次数Rh.key) h=j; /确定最小值 if(h!=i) R0.key=Ri.key; Ri.key=Rh.key; Rh.key=R0.key; /移动次数tt第%d趟选择排序的结果为:ntt比较次数:ntt移动次数:图六 选择排序4.1.6 堆排序 堆排序是一树形选择排序,在排序过程中,将R1.N看成是一颗完全二叉树的顺序存储结构,利用完全二叉树中双亲结点和孩子结点之间的内在关系来选择最小的元素。将原始记录序列建成一个堆,成为初始堆,并输出堆顶元素;调整剩余的记录序列,使之成为一个新堆,再输出堆顶元素
12、;如此反复进行,当堆中只有一个元素时,整个序列的排序结束,输出的序列便是原始序列的非递减有序序列。在堆排序的过程中,主要负责两方面的工作:一是如何将原始记录序列构造成一个堆,即建立初始堆;二是输出堆顶元素后,如何将剩余记录整理成一个新堆。void CreateHeap(int root,int index,int *x,int *y) int j,temp,finish; j=2*root; /j指向左孩子 temp=Rroot.key; finish=0; while(j=index&finish=0) if(jindex) if(Rj.key=Rj.key) finish=1; else
13、Rj/2.key=Rj.key; (*y)+; j=j*2; *x = *x+2; Rj/2.key=temp; (*y)+;/堆排序void Heapsort() int i,j,temp,k,x=0,y=0; for(i=(L/2);i=1;i-) /建立初始堆 CreateHeap(i,L,&x,&y); x=0; y=0; for(i=L-1,k=1;i-,k+) /将堆中根节点和最后一个节点交换 temp=Ri+1.key; Ri+1.key=R1.key; R1.key=temp; CreateHeap(1,i,&tt第%d趟堆排序的结果为:,k);,Rj.key);%dttvoi
14、d Heap() int i; Heapsort();void Merge(int low,int mm,int high,int *x,int *y)/两个有序序列的合并 int i=low,j=mm+1,p=0; RecType *R1; /i对第一个开始到结尾,j从第二个开始到结尾 R1=new RecTypehigh-low+1; if(!R1)内存不足!=mm&=high)/两序列从起始位置开始将小的元素放入到R1中 R1p+=(Ri.key=Rj.key)?Ri+:Rj+; (*x)+; (*y)+;=mm)/第二段结束,剩余放入R1中 R1p+=Ri+;=high)/第二段剩余,剩余放入R1中 R1p+=Rj+; for(p=0,i=low;=high;p+,i+)/剩余元素放入R1中,赋予R Ri=R1p;图七 堆排序4.1.7 归并排序将有n个记录的原始序列看作n个有序子序列,每个子序列的长度为1,然后从第一个子序列开始,把相邻的子序列两两合
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1