快速排序算法_带你图解排序算法之——快速排序算法(二)

   抽奖活动最后一天了  

点击下方蓝字即可跳转活动

我们在国庆节当天搞了个抽奖送书活动,10月5日就要开奖了,超高中奖率,参与≈中奖噢。

今天,我想宣布一个事,顺便送几本书


01

引言

Introduction

只要涉及到数据,就会涉及到数据的排序问题,比如给你随机给你十个整数  6,1,2,7,9,3,4,5,10,8。让你从小到大进行排序,那我们该怎样才是实现对这些整数的排序呢 ? 3eb1d40110447ab8c9132f5839b06c49.png 答案是多种多样的,比如用 冒泡排序 、选择排序、堆排序、归并排序、 快速排序 等等,这些排序方法都可以实现对整数排序,而这篇文章要讲的就是 快速排序 本文将从以下几个问题对快速排序进行分析和讲解:  1   快速 排序的算法思想及其大概过程怎样的?  2    怎样用代码实现快速排序?  3   快速 排序的代码详解
02

 快速排序的思想和过程 

The idea and process of quicksort

算法思想

树立一个基准数(以此数作为比较的标杆),分别从数组两边进行探测查找,右边的探测结束条件为找到一个比基准数小的数,左边的探测结束条件为找到一个基准数大的数,当左右两边的探测都结束后,交换这两个数;重复以上过程,直到两边探测的索引相遇(一致)。最后将基准数与索引相遇的位置上的数交换。

我们用快速排序讲一个例子来说明,要排序的数组为:{6,1,2,7,9,3,4,5,10,8}

01302cfac4ec51cbe51097caac0d0897.png

(图源啊哈算法)

注:i,j分别为左右两端的探测,姑且称它们为哨兵.

图解过程

01

首先哨兵 j开始出动。因为此处设置的基准数是最左边的数,所以需要让哨兵j先出动,这一点非常重要(请自己想一想为什么)。哨兵j一步一步地向左挪动(即j–),直到找到一个小于6的数停下来。接下来哨兵i再一步一步向右挪动(即i++),直到找到一个数大于6的数停下来。最后哨兵j停在了数字5面前,哨兵i停在了数字7面前。

64e456be160912d0bac16af6e99694b5.png

(图源啊哈算法)

现在交换哨兵i和哨兵j所指向的元素的值。交换之后的序列如下:

6  1  2  5  9   3  4  7  10  8

02

d0079a04e6696ce6cc3c9aabb176da38.png

(图源啊哈算法)

到此,第一次交换结束。接下来哨兵继续向左挪动。它发现了4之后停了下来。哨兵i也继续向右挪动,它发现9之后停了下来。此时再次进行交换,再次进行交换,交换之后的序列如下:

b1920c2dd9e1ec2214181283cccfa3f6.png

(图源啊哈算法)

6  1  2  5  4  3  9  7  10  8

03

第二次交换结束,探测继续。哨兵j继续向左挪动,它发现了3之后又停了下来。此时哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。说明此时探测结束。我们将基准数6和3进行交换。交换之后的序列如下。

8615b07df56073b982cf9ec53346b924.png

4f1973f674610df88f326a861f8c063c.png

(图源啊哈算法)

3    1    2    5    4    6     9    7    10   8

到此第一轮探测真正结束,此时以 6 为分界点,6左边的数都小于等于6,6右边的数都大于等于6。
此时我们已经将原来的序列以6为分界点拆分成了两个序列, 左边序列 {3,1,2,5,4} , 右边序列{9,7,10,8} ,接下来只需要再以上述同样的方法对这两个序列分别进行排序即可。
void QuickSort(int arr[],int first,int last){  if(first>last)//控制递归结束     return ;  int i=first,j=last;  int temp=arr[first];//基准数  while(i!=j)//i和j不碰头   {    //顺序很重要,要先从右往左找     while(arr[j]>=temp&&i      j--;    //上面循环结束的条件有两种,    //一是查到了比基准数小的,    //二是 i与j碰头了    while(arr[i]<=temp && i      i++;     //循环结束条件同上        //下面交换两个数在数组中的位置    if(i//两个循环结束的条件都不是i和j碰头    {      int t=arr[i];      arr[i]=arr[j];      arr[j]=t;    }   }   //最终一定会碰头,交换基准数和碰头那个位置的数   arr[first]=arr[i];  arr[i]=temp;        //QuickSort(arr,first,i-1);分的前一部分   //QuickSort(arr,i+1,last); 分的后一部分 }

03

 怎样用代码实现快速排序 

How to implement quicksort in code

 1    我们实现基数数的移动,注意两个哨兵移动时,移动要哨兵j先移动,然后再哨兵i移动  2   实现分的过程,注意要以什么为分割线进行
#includeusing namespace std;//快速排序函数    不稳定 void QuickSort(int arr[],int first,int last){  if(first>last)//控制递归结束     return ;  int i=first,j=last;  int temp=arr[first];//基准数  while(i!=j)//i和j不碰头   {    //顺序很重要,要先从右往左找     while(arr[j]>=temp&&i      j--;    //上面循环结束的条件有两种,    //一是查到了比基准数小的,    //二是 i与j碰头了    while(arr[i]<=temp && i      i++;     //循环结束条件同上        //下面交换两个数在数组中的位置    if(i//两个循环结束的条件都不是i和j碰头    {      int t=arr[i];      arr[i]=arr[j];      arr[j]=t;    }   }   //最终一定会碰头,交换基准数和碰头那个位置的数   arr[first]=arr[i];  arr[i]=temp;        QuickSort(arr,first,i-1);//分的前一部分   QuickSort(arr,i+1,last); //分的后一部分 }//输出数组的值void printf(int arr[],int len){  for(int i=0;i    cout<" ";  cout<<endl;}int main(){  //要排序的数组   int arr[]={6,1,2,7,9,3,4,5,10,8};  int len=10;//要排序的数组长度     //排序   QuickSort(arr,0,len-1);    //输出   printf(arr,len);  return 0;}

4c2e0655772ef0b40f5da9d9e0486846.gif

6d8a50ed1d7b15a77db3527cbce59c04.gif

 往期推荐 

🔗带你图解排序算法之——冒泡排序算法(一)

ef01f466e78f0284a2b33e7f1c02684e.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值