快速排序 算法学习笔记

转载 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()函数是进行一次快排的算法。 
对于快速排序的一次排序,有很多种算法,我这里列举三种。

左右指针法

  1. 选取一个关键字(key)作为枢轴,一般取整组记录的第一个数/最后一个,这里采用选取序列最后一个数为枢轴。
  2. 设置两个变量left = 0;right = N - 1;
  3. 从left一直向后走,直到找到一个大于key的值,right从后至前,直至找到一个小于key的值,然后交换这两个数。
  4. 重复第三步,一直往后找,直到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 }

挖坑法

  1. 选取一个关键字(key)作为枢轴,一般取整组记录的第一个数/最后一个,这里采用选取序列最后一个数为枢轴,也是初始的坑位。
  2. 设置两个变量left = 0;right = N - 1;
  3. 从left一直向后走,直到找到一个大于key的值,然后将该数放入坑中,坑位变成了array[left]。
  4. right一直向前走,直到找到一个小于key的值,然后将该数放入坑中,坑位变成了array[right]。
  5. 重复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 }

前后指针法

  1. 定义变量cur指向序列的开头,定义变量pre指向cur的前一个位置。
  2. 当array[cur] < key时,cur和pre同时往后走,如果array[cur]>key,cur往后走,pre留在大于key的数值前一个位置。
  3. 当array[cur]再次 < key时,交换array[cur]和array[pre]。

通俗一点就是,在没找到大于key值前,pre永远紧跟cur,遇到大的两者之间机会拉开差距,中间差的肯定是连续的大于key的值,当再次遇到小于key的值时,交换两个下标对应的值就好了。

扫描二维码关注公众号,回复: 3430300 查看本文章

带着这种思想,看着图示应该就能理解了。

下面是实现代码:

 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 }

返回 算法学习笔记

猜你喜欢

转载自www.cnblogs.com/Toya/p/9745989.html