归并排序 && 快速排序
归并排序:
归并排序比较占用内存,但却是一种效率高且稳定的算法。
具体思路是,在归并的过程中计算每个小区间的逆序对数,进而计算出大区间的逆序对数。
归并排序是稳定的排序.即相等的元素的顺序不会改变.如输入记录 1(1) 3(2) 2(3) 2(4) 5(5) (括号中是记录的关键字)时输出的 1(1) 2(3) 2(4) 3(2) 5(5) 中的2 和 2 是按输入的顺序.这对要排序数据包含多个信息而要按其中的某一个信息排序,要求其它信息尽量按输入的顺序排列时很重要.这也是它比快速排序优势的地方.
1 #include <cstdio> 2 int cnt=0; 3 int x1[50010],x2[50010]; 4 void Merge(int a[],int b[],int left,int middle,int right) 5 { 6 int i=left,j=middle+1,k=left; 7 while(i!=middle+1&&j!=right+1) 8 { 9 if(a[i]<=a[j]) 10 { 11 b[k++]=a[i++]; 12 } 13 else 14 { 15 cnt+=middle-i+1; //归并排序求逆序数 16 b[k++]=a[j++]; 17 } 18 // printf("%d\n",cnt); 19 } 20 while(i!=middle+1) 21 { 22 b[k++]=a[i++]; 23 } 24 while(j!=right+1) 25 { 26 b[k++]=a[j++]; 27 } 28 for(int i=left;i<=right;i++) 29 { 30 a[i]=b[i]; 31 //printf("%d ",a[i]); 32 } 33 //printf("\n"); 34 } 35 36 void Merge_sort(int a[],int b[],int left,int right) 37 { 38 int middle; 39 if(left<right) 40 { 41 middle=(left+right)/2; 42 //printf("%d %d %d\n",left,right,middle); 43 Merge_sort(a,b,left,middle); 44 Merge_sort(a,b,middle+1,right); 45 Merge(a,b,left,middle,right); 46 } 47 return; 48 } 49 50 int main() 51 { 52 // freopen("a.txt","r",stdin); 53 int n; 54 scanf("%d",&n); 55 for(int i=0;i<n;i++) 56 { 57 scanf("%d",&x1[i]); 58 } 59 Merge_sort(x1,x2,0,n-1); 60 printf("%d\n",cnt); 61 return 0; 62 }
快速排序:
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
快速排序不是一种稳定的排序算法,也就是说,多个相同的值的相对位置也许会在算法结束时产生变动。
1 #include <cstdio> 2 3 void qsort(int a[],int left,int right) 4 { 5 if(left>=right) //完成一次 排序 6 { 7 return; 8 } 9 int key=a[left],i=left,j=right; 10 while(i<j) 11 { 12 while(i<j&&key<=a[j]) 13 { //从后往前查找 比key小的数丢到前面去 14 j--; 15 } 16 a[i]=a[j]; 17 while(i<j&&key>=a[i]) 18 { //从前往后查找 比key大的数丢到后面去 19 i++; 20 } 21 a[j]=a[i]; 22 } 23 a[i]=key; //在key左边的都比key小,右边的都比key大 24 qsort(a,left,i-1); //继续递归 直到 剩下一个数 25 qsort(a,i+1,right); 26 } 27 int main() 28 { 29 int a[8]={23,10,34,5,9,39,84,77}; 30 qsort(a,0,7); 31 for(int i=0;i<8;i++) 32 printf("%d\n",a[i]); 33 return 0; 34 }