转载 https://blog.csdn.net/qq_36528114/article/details/78667034
快速排序(Quick Sort)是对冒泡排序的一种改进,基本思想是选取一个记录作为枢轴,经过一趟排序,将整段序列分为两个部分,其中一部分的值都小于枢轴,另一部分都大于枢轴。然后继续对这两部分继续进行排序,从而使整个序列达到有序。
递归实现:
1 void QuickSort(int* array, int left, int right){ 2 assert(array); 3 if(left>=right) 4 return; 5 int index= PartSort(array, left, right); 6 QuickSort(array, left, index-1); 7 QuickSort(array, index+1, right); 8 }
PartSort()函数是进行一次快排的算法。
对于快速排序的一次排序,有很多种算法,我这里列举三种。
左右指针法
- 选取一个关键字(key)作为枢轴,一般取整组记录的第一个数/最后一个,这里采用选取序列最后一个数为枢轴。
- 设置两个变量left = 0;right = N - 1;
- 从left一直向后走,直到找到一个大于key的值,right从后至前,直至找到一个小于key的值,然后交换这两个数。
- 重复第三步,一直往后找,直到left和right相遇,这时将key放置left的位置即可。
当left >= right时,一趟快速排序就完成了,这时将Key和array[left]的值进行一次交换。
一次快排的结果:4 1 3 0 2 5 9 8 6 7
基于这种思想,可以写出代码:
1 int PartSort(int* array, int left, int right){ 2 int key& = array[right]; 3 while(left < right){ 4 while(left < right && array[left] <= key){ 5 ++left; 6 } 7 while(left < right && array[right ] >= key){ 8 --right; 9 } 10 swap(array[left],array[right]); 11 } 12 }
挖坑法
- 选取一个关键字(key)作为枢轴,一般取整组记录的第一个数/最后一个,这里采用选取序列最后一个数为枢轴,也是初始的坑位。
- 设置两个变量left = 0;right = N - 1;
- 从left一直向后走,直到找到一个大于key的值,然后将该数放入坑中,坑位变成了array[left]。
- right一直向前走,直到找到一个小于key的值,然后将该数放入坑中,坑位变成了array[right]。
- 重复3和4的步骤,直到left和right相遇,然后将key放入最后一个坑位。
当left >= right时,将key放入最后一个坑,就完成了一次排序。
注意,left走的时候right是不动的,反之亦然。因为left先走,所有最后一个坑肯定在array[right]。
写出代码:
1 int PartSort(int* array,int left,int right) 2 { 3 int key = array[right]; 4 while(left < right) 5 { 6 while(left < right && array[left] <= key) 7 { 8 ++left; 9 } 10 array[right] = array[left]; 11 while(left < right && array[right] >= key) 12 { 13 --right; 14 } 15 array[left] = array[right]; 16 } 17 array[right] = key; 18 return right; 19 }
前后指针法
- 定义变量cur指向序列的开头,定义变量pre指向cur的前一个位置。
- 当array[cur] < key时,cur和pre同时往后走,如果array[cur]>key,cur往后走,pre留在大于key的数值前一个位置。
- 当array[cur]再次 < key时,交换array[cur]和array[pre]。
通俗一点就是,在没找到大于key值前,pre永远紧跟cur,遇到大的两者之间机会拉开差距,中间差的肯定是连续的大于key的值,当再次遇到小于key的值时,交换两个下标对应的值就好了。
带着这种思想,看着图示应该就能理解了。
下面是实现代码:
1 int PartSort(int* array,int left,int right) 2 { 3 if(left < right){ 4 int key = array[right]; 5 int cur = left; 6 int pre = cur - 1; 7 while(cur < right) 8 { 9 while(array[cur] < key && ++pre != cur)//如果找到小于key的值,并且cur和pre之间有距离时则进行交换。注意两个条件的先后位置不能更换,可以参照评论中的解释 10 { 11 swap(array[cur],array[pre]); 12 } 13 ++cur; 14 } 15 swap(array[++pre],array[right]); 16 return pre; 17 } 18 return -1; 19 }