c语言各种排序法详解

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

实用文档标准文案一插入排序1.1直接插入排序基本思想:每次将一个待排序额记录按其关键码的大小插入到一个已经排好序的有序序列中,直到全部记录排好序。图解:代码实现:[cpp]viewplaincopy1.//直接顺序排序2.voidInsertSort(intr[],intn)3.{4.for(inti=2;in;i++)实用文档标准文案5.{6.r[0]=r[i];//设置哨兵7.for(intj=i-1;r[0]r[j];j--)//寻找插入位置8.r[j+1]=r[j];//记录后移9.r[j+1]=r[0];10.}11.for(intk=1;kn;k++)12.coutr[k];13.cout\n;14.}1.2希尔排序基本思想是:先将整个待排序记录序列分割成若干个子序列,在在序列内分别进行直接插入排序,待整个序列基本有序时,再对全体记录进行一次直接插入排序。图解:代码实现:[cpp]viewplaincopy1.spanstyle=font-size:14px;//希尔排序2.voidShellSort(intr[],intn)3.{4.inti;实用文档标准文案5.intd;6.intj;7.for(d=n/2;d=1;d=d/2)//以增量为d进行直接插入排序8.{9.for(i=d+1;in;i++)10.{11.r[0]=r[i];//暂存被插入记录12.for(j=i-d;j0&&r[0]r[j];j=j-d)13.r[j+d]=r[j];//记录后移d个位置14.r[j+d]=r[0];15.}16.}17.for(i=1;in;i++)18.coutr[i];19.cout\n;20.}/span二交换排序2.1起泡排序起泡排序是交换排序中最简单的排序方法,其基本思想是:两两比较相邻记录的关键码,如果反序则交换,直到没有反序的记录为止。图解:实用文档标准文案代码实现:[cpp]viewplaincopy1.spanstyle=font-size:14px;//起泡排序2.voidBubbleSort(intr[],intn)3.{4.inttemp;5.intexchange;6.intbound;7.exchange=n-1;//第一趟起泡排序的范围是r[0]到r[n-1]8.while(exchange)//仅当上一趟排序有记录交换才进行本趟排序9.{10.bound=exchange;11.exchange=0;12.for(intj=0;jbound;j++)//一趟起泡排序13.if(r[j]r[j+1])14.{实用文档标准文案15.temp=r[j];16.r[j]=r[j+1];17.r[j+1]=temp;18.exchange=j;//记录每一次发生记录交换的位置19.}20.}21.for(inti=0;in;i++)22.coutr[i];23.cout\n;24.}/span2.2快速排序基本思想:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。图解:实用文档标准文案代码实现:[cpp]viewplaincopy1.//快速排序一次划分2.intPartition(intr[],intfirst,intend)3.{4.inti=first;//初始化5.intj=end;实用文档标准文案6.inttemp;7.8.while(ij)9.{10.while(ij&&r[i]=r[j])11.j--;//右侧扫描12.if(ij)13.{14.temp=r[i];//将较小记录交换到前面15.r[i]=r[j];16.r[j]=temp;17.i++;18.}19.while(ij&&r[i]=r[j])20.i++;//左侧扫描21.if(ij)22.{23.temp=r[j];24.r[j]=r[i];25.r[i]=temp;//将较大记录交换到后面26.j--;27.}28.}29.returni;//i为轴值记录的最终位置30.}31.32.//快速排序33.voidQuickSort(intr[],intfirst,intend)34.{35.if(firstend)36.{//递归结束37.intpivot=Partition(r,first,end);//一次划分38.QuickSort(r,first,pivot-1);//递归地对左侧子序列进行快速排序39.QuickSort(r,pivot+1,end);//递归地对右侧子序列进行快速排序40.}41.42.}三选择排序实用文档标准文案3.1简单选择排序基本思想:设所排序序列的记录个数为n。i取1,2,…,n-1,从所有n-i+1个记录(Ri,Ri+1,…,Rn)中找出排序码最小的记录,与第i个记录交换。执行n-1趟后就完成了记录序列的排序。图解:代码实现:[cpp]viewplaincopy1.//简单选择排序2.voidSelectSort(intr[],intn)3.{4.inti;5.intj;6.intindex;7.inttemp;实用文档标准文案8.for(i=0;in-1;i++)//对n个记录进行n-1趟简单选择排序9.{10.index=i;11.for(j=i+1;jn;j++)//在无序区中选取最小记录12.if(r[j]r[index])13.index=j;14.if(index!=i)15.{16.temp=r[i];17.r[i]=r[index];18.r[index]=temp;19.}20.}21.for(i=0;in;i++)22.coutr[i];23.cout\n;24.}3.2堆排序堆的定义堆是具有下列性质的完全二叉树:每个结点的值都小于或等于其左右孩子结点的值(小根堆);或者每个结点的值都大于或等于其左右孩子结点的值(大根堆)。大根堆和小根堆:根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最小者的堆称为小根堆,又称最小堆。根结点(亦称为堆顶)的关键字是堆里所有结点关键字中最大者,称为大根堆,又称最大堆。注意:①堆中任一子树亦是堆。②以上讨论的堆实际上是二叉堆(BinaryHeap),类似地可定义k叉堆。实用文档标准文案假设当前要筛选结点的编号为k,堆中最后一个结点的编号为m,并且结点k的左右子树均是堆(即r[k+1]~r[m]满足堆的条件),则筛选算法用伪代码可描述为:具体的筛选代码如下:[cpp]viewplaincopy1.//筛选法调整堆2.voidSift(intr[],intk,intm)实用文档标准文案3.{4.5.inti;6.intj;7.inttemp;8.i=k;9.j=2*i+1;//置i为要筛的结点,j为i的左孩子10.while(j=m)//筛选还没有进行到叶子11.{12.if(jm&&r[j]r[j+1])13.j++;//比较i的左右孩子,j为较大者14.if(r[i]r[j])break;//根结点已经大于左右孩子中的较大者15.else16.{17.temp=r[i];18.r[i]=r[j];19.r[j]=temp;//将根结点与结点j交换20.i=j;21.j=2*i+1;//被筛结点位于原来结点j的位置22.}23.}24.}堆排序堆排序的基本思想是:首先将待排序的记录序列构造成一个堆,此时,选出了堆中所有记录的最大者即堆顶记录,然后将它从堆中移走(通常将堆顶记录和堆中最后一个记录交换),并将剩余的记录再调整成堆,这样又找出了次大的记录,以此类推,直到堆中只有一个记录为止。(1)用大根堆排序的基本思想①先将初始文件R[1..n]建成一个大根堆,此堆为初始的无序区②再将关键字最大的记录R[1](即堆顶)和无序区的最后一个记录R[n]交换,由此得到新的无序区R[1..n-1]和有序区R[n],且满足R[1..n-1].keys≤R[n].key③由于交换后新的根R[1]可能违反堆性质,故应将当前无序区R[1..n-1]调整为堆。然后再次将R[1..n-1]中关键字最大的记录R[1]和该区间的最后一个记录R[n-1]交换,由此得到新的无序区R[1..n-2]和有序区R[n-1..n],且仍满足关系R[1..n-2].keys≤R[n-1..n].keys,同样要将R[1..n-2]调整为堆。实用文档标准文案……直到无序区只有一个元素为止。(2)大根堆排序算法的基本操作:①初始化操作:将R[1..n]构造为初始堆;②每一趟排序的基本操作:将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆(亦称重建堆)。注意:①只需做n-1趟排序,选出较大的n-1个关键字即可以使得文件递增有序。②用小根堆排序与利用大根堆类似,只不过其排序结果是递减有序的。堆排序和直接选择排序相反:在任何时刻堆排序中无序区总是在有序区之前,且有序区是在原向量的尾部由后往前逐步扩大至整个向量为止实用文档标准文案实用文档标准文案代码实现:[cpp]viewplaincopy实用文档标准文案1.//堆排序2.voidHeapSort(intr[],intn)3.{4.5.inti;6.inttemp;7.for(i=n/2;i=0;i--)//初始建堆,从最后一个非终端结点至根结点8.Sift(r,i,n);9.for(i=n-1;i0;i--)//重复执行移走堆顶及重建堆的操作10.{11.temp=r[i];12.r[i]=r[0];13.r[0]=temp;14.Sift(r,0,i-1);15.}16.for(i=0;in;i++)17.coutr[i];18.cout\n;19.}四归并排序二路归并排序基本思想:将若干个有序序列进行两两归并,直至所有待排序记录都在一个有序序列为止。实用文档标准文案一路归并算法实现:[cpp]viewplaincopy1.//一次归并2.voidMerge(intr[],intr1[],ints,intm,intt)3.{4.5.inti=s;6.intj=m+1;7.intk=s;8.9.while(i=m&&j=t)10.{11.if(r[i]=r[j])12.r1[k++]=r[i++];//取r[i]和r[j]中较小者放入r1[k]13.else14.r1[k++]=r[j++];15.}16.if(i=m)17.while(i=m)//若第一个子序列没处理完,则进行收尾处理18.r1[k++]=r[i++];19.else20.while(j=t)//若第二个子序列没处理完,则进行收尾处理21.r1[k++]=r[j++];实用文档标准文案22.}[cpp]viewplaincopy1.//一趟归并2.voidMergePass(intr[],intr1[],intn,inth)3.{4.inti=0;5.intk;6.7.while(i=n-2*h)//待归并记录至少有两个长度为h的子序列8.{9.Merge(r,r1,i,i+h-1,i+2*h-1);10.i+=2*h;11.}12.if(in-h)实用文档标准文案13.Merge(r,r1,i,i+h-1,n);//待归并序列中有一个长度小于h14.elsefor(k=i;k=n;k++)//待归并序列中只剩一个子序列15.r1[k]=r[k];16.}17.18.//归并排序的非递归算法19.voidMergeSort1(intr[],intr1[],intn)20.{21.inth=1;22.inti;23.24.while(hn)25.{26.MergePass(r,r1,n-1,h);//归并27

1 / 20
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功