zoukankan      html  css  js  c++  java
  • 快速排序

    转载 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的值时,交换两个下标对应的值就好了。

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

    下面是实现代码:

     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 }
  • 相关阅读:
    HDU5730 Shell Necklace
    BZOJ4883 [Lydsy2017年5月月赛]棋盘上的守卫
    Spring boot 配置文件
    org.joda.time.DateTime 日期操作
    Elasticsearch + Springboot 启动报错 java.net.ConnectException: Connection refused
    centos7 在docker下安装es Elasticsearch
    centos 7 。 docker 安装rabbitmq 以及集权搭建
    linux 安装mysql5.7.25
    安装rabbtimq CentOS 7
    docker + spring boot 打包 部署。
  • 原文地址:https://www.cnblogs.com/Toya/p/9745989.html
Copyright © 2011-2022 走看看