标签:
交换排序是指在排序过程中,通过比较待排序记录序列中元素间关键字的比较,将存储位置进行交换来达到排序目的的方法。
#include<stdio.h> #include<stdlib.h> #include<math.h> //冒泡排序,一次排序将无序区里面最大的移到最右边 void BubbleSort(int* a,int length) { int i=0,j=0; int temp; for(i=length-1;i>0;i--) { for(j=0;j<i;j++) { if(a[j+1]<a[j]) { temp=a[j+1]; a[j+1]=a[j]; a[j]=temp; } } } } //优化后的冒泡排序:一点是如果一趟排序没有进行任何交换,那么说明已经有序,这样程序应该退出; // 一点是一趟排序中,最后一次交换的地方,此时的j以后的全部有序了,因此下次可从此时的j开始; void BetterBubbleSort(int* a,int length) { int i=0,j=0; int temp,m=0,n=length-1,last; for(i=length-1;i>0;i=n) { m=0; last=n; for(j=0;j<=last;j++) { if(a[j+1]<a[j]) { temp=a[j+1]; a[j+1]=a[j]; a[j]=temp; m=1; n=j; } } if(m==0)//说明此时无序区里的所有数据已经有序,可以退出 break; } } //我自己写的快排,可以清晰的看出它的原理 void QuickSort(int* a,int start,int end) { int s=start; int e=end-1; int m=s; int temp; while(s<e) { while(a[e]>=a[m]&&s<e) e--; if(a[e]<a[m]) { temp=a[e]; a[e]=a[m]; a[m]=temp; m=e; } while(a[s]<=a[m]&&s<e) s++; if(a[s]>a[m]) { temp=a[s]; a[s]=a[m]; a[m]=temp; m=s; } } if(m>start+1) QuickSort(a,start,m); if(m<end-1) QuickSort(a,m+1,end); } //更好的快速排序 void BetterQuickSort(int* a,int start,int end) { int s=start; int e=end; int m=a[s]; while(s<e) { //还有一点要格外注意当有重复数据时,比如这里2个5,程序会进入到死循环,调试发现此时a[e]=a[s],但是e与s不相等,所以要在while循环条件里加上>=或<=。 while(s<e&&a[e]>=m) e--; a[s]=a[e]; while(s<e&&a[s]<=m) s++; a[e]=a[s]; //我自己设的数组太长了,所以换了一个小的,假设数组a是3,2,5,8,1,9。经过一次while后为1 2 5 8 5 9,现在e=4,s=2 //这个地方我刚开始一直觉得还需要加上一个a[s]=m;,想清楚后才发现并不需要加,原因可分为2种情况, //首先下一次执行while循环时是从后往前进行比较的,正好上一次a[e]=a[s]导致a[e]是大于m的,所以e一直减减直到条件不满足退出,然后再在while循环后执行a[s]=m; //第二种情况是假设把8替换为0,这样的话e将变为3,此时s=2数组为1 2 0 0 5 9,注意接下来是s开始向前增加了,正是由于将较小值放在前面,所以s一直加加直到条件不满足退出 //当需要多次while循环时将会完成多次上述2种情况,总之就是可以保证s与e一直在增加与减少。 } a[s]=m; if(s>start+1) BetterQuickSort(a,start,s-1); if(s<end-1) BetterQuickSort(a,s+1,end); } void main() { //交换排序 int a[]={5,2,7,23,5,10,12,1,21}; int length=9; int i=0; //冒泡排序,序列越有序它的效率越高。它是一种稳定的排序方法,平均时间复杂度为O(n^2) //BubbleSort(a,length); //BetterBubbleSort(a,length); //快速排序,可以看出它适合杂乱无章的数据,如果数据有序的话可能一次只会划分很小的区域。 //对于时间复杂度,假设一种极端情况,每次选择的都是最小的或最大的,设序列区长度为k,那这样就直接比较了k-1次。整个时间复杂度是(k-1)*(k-2)..,这样就退化为冒泡了,所以时间复杂度是O(n^2); //最好情况是每次划分序列后这两个序列长度相等,那一次排序,就算你是划分了几个序列区域去排序。我自己举例子发现第一次比较n-1次,第二次划分一般那就是n/2-1,但是由于有2部分所以要乘以2。 //也就是说一次排序比较的次数是n阶函数,而划分一半的次数是lbn,故时间复杂度是O(nlbn) //QuickSort(a,0,length); BetterQuickSort(a,0,length-1); for(;i<length;i++) printf("%d ",a[i]); }
标签:
原文地址:http://www.cnblogs.com/fangyz/p/5425751.html