1.冒泡排序已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先比较a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。再比较a[2]与a[3]的值,若a[2]大于a[3]则交换两者的值,否则不变。再比较a[3]与a[4],以此类推,最后比较a[n-1]与a[n]的值。这样处理一轮后,a[n]的值一定是这组数据中最大的。再对a[1]~a[n-1]以相同方法处理一轮,则a[n-1]的值一定是a[1]~a[n-1]中最大的。再对a[1]~a[n-2]以相同方法处理一轮,以此类推。共处理n-1轮后a[1]、a[2]、……a[n]就以升序排列了。 优点:稳定,比较次数已知;缺点:慢,每次只能移动相邻两个数据,移动数据的次数多。 初始关键字 [49 3865 97 76 13 27 49]第一趟排序后 [38 4965 76 13 27 49] 97第二趟排序后 [38 4965 13 27 49] 76 97第三趟排序后 [38 4913 27 49] 65 76 97第四趟排序后 [38 1327 49] 49 65 76 97第五趟排序后 [38 1327] 49 49 65 76 97第六趟排序后 [13 27]38 49 49 65 76 97第七趟排序后 [13] 2738 49 49 65 76 97最后排序结果 13 2738 49 49 76 76 97 #include <iostream>using namespace std;void main() { int i,j,k; int a[8]={49,38,65,97,76,13,27,49}; for(i=7;i>=0;i--) { for(j=0;j<i;j++) { if(a[j]>a[j+1]) { k=a[j]; a[j]=a[j+1]; a[j+1]=k; } } } for(i=0;i<8;i++) cout<<a<<endl; } 2.选择排序 ①初始状态:无序区为R[1..n],有序区为空。 ②第1趟排序 在无序区R[1..n]中选出关键字最小的记录R[k],将它与无序区的第1个记录R[1]交换,使R[1..1]和R[2..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区。…… ③第i趟排序第i趟排序开始时,当前有序区和无序区分别为R[1..i-1]和R[i..n](1≤i≤n-1)。该趟排序从当前无序区中选出关键字最小的记录R[k],将它与无序区的第1个记录R交换,使R[1..i]和R[i+1..n]分别变为记录个数增加1个的新有序区和记录个数减少1个的新无序区.这样,n个记录的文件的直接选择排序可经过n-1趟直接选择排序得到有序结果。 优点:稳定,比较次数与冒泡排序一样;缺点:相对之下还是慢。 初始关键字 [49 3865 97 76 13 27 49]第一趟排序后 13 〔38 65 97 76 49 27 49]第二趟排序后 13 27 〔65 97 76 49 38 49]第三趟排序后 13 2738 [97 76 49 65 49]第四趟排序后 13 2738 49 [49 97 65 76]第五趟排序后 13 2738 49 49 [97 97 76]第六趟排序后 13 2738 49 49 76 [76 97]第七趟排序后 13 2738 49 49 76 76 [ 97]最后排序结果 13 2738 49 49 76 76 97 #include <iostream>using namespace std;void main(){ int i,j,k,t; int R[8]={49,38,65,97,76,13,27,49}; for(i=0;i<7;i++) { k=i; for(j=i+1;j<8;j++) if(R[j]<R[k]) k=j; if(k!=i) { t=R[j];R[j]=R[k];R[k]=t; } }for(i=0;i<8;i++) cout<<R<<endl; }
3.插入排序已知一组,一组无序数据b[1]、b[2]、……b[m],需将其变成一个升序数列。先创建一个变量a。首先将不b[1]与b[2],如果b[1]大于b[2]则交换位置,否则不变;再比较b[2]与b[3],如果b[3]小于b[2],则将b[3]赋值给a,再将a与b[1]比较,如果a小于b[1];则将b[2],b[1]依次后移;在将a放在b[1]处以此类推,直到排序结束。初始关键字 [49 3865 97 76 13 27 59] a b[1] b[2] b[3] b[4] b[5] b[6] b[7] b[8]1-----49 49 > 38 65 97 76 13 27 5938 49 49 ……….38 38 49 ……….2-----38 38 49 < 65 97 76 13 27 593-----38 38 49 65 <97 76 13 27 594----38 38 49 65 97> 76 13 27 5976 38 49 65 97 97……..76 38 49 65 76 97……..以此类推void insertSort(Type* arr,long len){ long i=0,j=0; for(i=1;i<len;i++) { j=i; tmpData=arr[j];//tmpData用来储存数据 while(tmpData<arr[j-1]&&j>0) { arr[j]=arr[j-1]; j--; } arr[j]=tmpData; }}4.缩小增量排序(希尔排序)由希尔在1959年提出,又称希尔排序。已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。发现当n不大时,插入排序的效果很好。首先取一增量d(d<n),将a[1]、a[1+d]、a[1+2d]……列为第一组,a[2]、a[2+d]、a[2+2d]……列为第二组……,a[d]、a[2d]、a[3d]……列为最后一组以次类推,在各组内用插入排序,然后取d'<d,重复上述操作,直到d=1。增量d(1, 3, 7,15, 31, …, 2^k-1)是使用最广泛的增量序列之一.优点:快,数据移动少;缺点:不稳定,d的取值是多少,应取多少个不同的值,都无法确切知道,只能凭经验来取。初始:d=5 49 38 65 97 76 13 27 49 55 44 一趟结果 13 27 49 55 44 49 38 65 97 76 d=3 |----------------------|----------------------|---------------------| 二趟结果 13 44 49 38 27 49 55 65 97 76 d=1 三趟结果 13 27 38 44 49 49 55 65 76 97 #include <iostream>using namespace std;#define MAX 16 void shell_sort(int *x, int n){ inth, j, k, t; for(h=n/2;h>0; h=h/2) /*控制增量*/ { for(j=h; j<n; j++) /*这个实际上就是上面的直接插入排序*/ { t= *(x+j); for(k=j-h; (k>=0 && t<*(x+k)); k-=h) { *(x+k+h)= *(x+k); } *(x+k+h)= t; } }}void main(){ int*p, i, a[MAX]; p= a; cout<<"InputMAX number for sorting :"<<endl; for(i=0; i<MAX; i++) cin>>*p++; p=a; shell_sort(p,MAX); for(p=a, i=0; i<MAX; i++) { cout<<*p++<<endl; } cout<<endl;}
5.快速排序快速排序是冒泡排序的改进版,是目前已知的最快的排序方法。已知一组无序数据a[1]、a[2]、……a[n],需将其按升序排列。首先任取数据a[x]作为基准。比较a[x]与其它数据并排序,使a[x]排在数据的第k位,并且使a[1]~a[k-1]中的每一个数据<a[x],a[k+1]~a[n]中的每一个数据>a[x],然后采用分治的策略分别对a[1]~a[k-1]和a[k+1]~a[n]两组数据进行快速排序。优点:极快,数据移动少;缺点:不稳定。分段插入排序void QuickSort(int *pData, int left, intright){int i, j;int middle,iTemp;i = left;j = right;middle =pData[(left + right) / 2]; //求中间值do{while((pData < middle) && (i < right)) //从左扫描大于中值的数i++;while((pData[j] > middle) && (j > left)) //从右扫描小于中值的数j--;if (i <=j) //找到了一对值{//交换iTemp =pData;pData =pData[j];pData[j] =iTemp;i++;j--;}} while (i<= j) ; //如果两边扫描的下标交错,就停止(完成一次)//当左边部分有值(left<j),递归左半边if(left<j)QuickSort(pData,left,j);//当右边部分有值(right>i),递归右半边if(right>i)QuickSort(pData,i,right);} 6.归并排序算法合并排序(MERGESORT)是又一类不同的排序方法,合并的含义就是将两个或两个以上的有序数据序列合并成一个新的有序数据序列,因此它又叫归并算法。它的基本思想就是假设数组A有N个元素,那么可以看成数组A是又N个有序的子序列组成,每个子序列的长度为1,然后再两两合并,得到了一个 N/2 个长度为2或1的有序子序列,再两两合并,如此重复,值得得到一个长度为N的有序数据序列为止,这种排序方法称为2—路合并排序。例如数组A有7个数据,分别是: 49 38 65 97 76 13 27,那么采用归并排序算法的操作过程如图7所示:初始值 [49] [38] [65] [97] [76] [13] [27]第一次合并之后 [38 49] [65 97] [13 76] [27]第二次合并之后 [38 49 65 97] [13 27 76]第三次合并之后 [13 27 38 49 65 76 97]合并算法的核心操作就是将一维数组中前后相邻的两个两个有序序列合并成一个有序序列。合并算法也可以采用递归算法来实现,形式上较为简单,但实用性很差。合并算法的合并次数是一个非常重要的量,根据计算当数组中有3到4个元素时,合并次数是2次,当有5到8个元素时,合并次数是3次,当有9到16个元素时,合并次数是4次,按照这一规律,当有N个子序列时可以推断出合并的次数是X(2 >=N,符合此条件的最小那个X)。其时间复杂度为:O(nlogn).所需辅助存储空间为:O(n)归并排序:#include <stdio.h>void merge(int a[],int p,int q,int r){int n1=q-p+1,n2=r-q,i,j,k;int l[1002],R[1002];for (i=1;i<=n1;i++)l=a[p+i-1];for (j=1;j<=n2;j++)R[j]=a[q+j];R[n2+1]=l[n1+1]=999999;i=j=1;for (k=p;k<=r;k++){if (l<=R[j]){a[k]=l;i++;}else{a[k]=R[j];j++;}}}void mergesort(int a[],int p,int r){int q;if (p<r){q=(p+r)/2;mergesort(a,p,q);mergesort(a,q+1,r);merge(a,p,q,r);}}int main(){int a[1001],t,n,i;scanf("%d",&t);while (t--){scanf("%d",&n);for(i=1;i<=n;i++)scanf("%d",&a);mergesort(a,1,n);for (i=1;i<=n;i++){printf("%d",a);if (i!=n)printf(" ");}printf("\n");}return 0;}
温馨提示:答案为网友推荐,仅供参考