标签:快速排序
1、快速排序
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
2、排序的过程
3、代码实现
三数取中法代码:
//优化一:三数取中法,避免出现最坏的情况 int GetMidIndex(int* a,int left,int right) { assert(a); int mid = left + (right- left)/2; if(a[left] > a[right]) { if(a[mid] > a[left]) { return left; } else { if(a[mid] > a[right]) return mid; else return right; } } else//right大 { if(a[mid] > a[right]) return right; else//right 大 { if(a[mid] > a[left]) return mid; else return left; } } }
快速排序的代码:
int PartSort1(int* a,int left,int right) { int mid = GetMidIndex(a,left,right); int key = a[mid]; int begin = left; int end = right-1; swap(a[mid],a[right]); while(begin <end) { while(begin <end && a[end] >=key) end--; while(begin <end && a[begin] <key) begin++; if(begin < end) swap(a[begin],a[end]); } if(a[begin] > a[right]) { swap(a[begin],a[right]); return begin; } else return begin; } void QuickSort(int* a,int left,int right) { //快速排序的第二种优化,将插入排序与快速排序结合 assert(a); if(left >= right) return; if(right -left < 16) { InsertSort(a+left,right-left+1); return; } else { int ret = PartSort1(a,left,right); QuickSort(a,left,ret-1); QuickSort(a,ret+1,right); } }
另外两种快速排序的方法:
//挖坑法 int PartSort2(int* a,int left,int right) { int mid = GetMidIndex(a,left,right); int key = a[mid]; int begin = left; int end = right;//初始时的坑 swap(a[mid],a[right]); while(begin < end) { while(begin < end && a[begin] <= key) begin++; if(begin < end) { a[end] = a[begin];//begin的位置变为坑 } while(begin < end && a[end] >= key) end--; if(begin < end) { a[begin] = a[end]; } } //跳出循环后,begin的位置为坑,将key放入 a[begin] = key; return begin; } //双指针法 int PartSort3(int* a,int left,int right) { int mid = GetMidIndex(a,left,right); int key = a[mid]; swap(a[mid],a[right]); int cur = 0; int prev = -1; while(cur < right) { if(a[cur] < key && (++prev != cur)) swap(a[cur],a[prev]); cur++; } prev++; swap(a[prev],a[cur]); return prev; }
4、时间复杂度
1)最好:O(N*logN)
在最好情况下,每次划分所取的基准都是当前无序区的"中值"记录,划分的结果是基准的左、右两个无序子区间的长度大致相等。总的关键字比较次数:O(NlogN)。
2)最坏:O(N*N)(key取得的值接近最大或最小)
最坏情况是每次划分选取的基准都是当前无序区中关键字最小(或最大)的记录,划分的结果是基准左边的子区间为空(或右边的子区间为空),而划分所得的另一个非空的子区间中记录数目,仅仅比划分前的无序区中记录个数减少一个。时间复杂度为O(N*N)。
本文出自 “LOVEMERIGHT” 博客,请务必保留此出处http://lovemeright.blog.51cto.com/10808587/1832176
标签:快速排序
原文地址:http://lovemeright.blog.51cto.com/10808587/1832176