抽奖活动最后一天了
点击下方蓝字即可跳转活动
▼▼▼
我们在国庆节当天搞了个抽奖送书活动,10月5日就要开奖了,超高中奖率,参与≈中奖噢。
今天,我想宣布一个事,顺便送几本书
01
引言
Introduction
只要涉及到数据,就会涉及到数据的排序问题,比如给你随机给你十个整数 6,1,2,7,9,3,4,5,10,8。让你从小到大进行排序,那我们该怎样才是实现对这些整数的排序呢 ? 答案是多种多样的,比如用 冒泡排序 、选择排序、堆排序、归并排序、 快速排序 等等,这些排序方法都可以实现对整数排序,而这篇文章要讲的就是 快速排序 本文将从以下几个问题对快速排序进行分析和讲解: 1 快速 排序的算法思想及其大概过程怎样的? 2 怎样用代码实现快速排序? 3 快速 排序的代码详解02
快速排序的思想和过程
The idea and process of quicksort
算法思想
树立一个基准数(以此数作为比较的标杆),分别从数组两边进行探测查找,右边的探测结束条件为找到一个比基准数小的数,左边的探测结束条件为找到一个基准数大的数,当左右两边的探测都结束后,交换这两个数;重复以上过程,直到两边探测的索引相遇(一致)。最后将基准数与索引相遇的位置上的数交换。我们用快速排序讲一个例子来说明,要排序的数组为:{6,1,2,7,9,3,4,5,10,8}
(图源啊哈算法)
注:i,j分别为左右两端的探测,姑且称它们为哨兵.
图解过程
01
首先哨兵 j开始出动。因为此处设置的基准数是最左边的数,所以需要让哨兵j先出动,这一点非常重要(请自己想一想为什么)。哨兵j一步一步地向左挪动(即j–),直到找到一个小于6的数停下来。接下来哨兵i再一步一步向右挪动(即i++),直到找到一个数大于6的数停下来。最后哨兵j停在了数字5面前,哨兵i停在了数字7面前。 (图源啊哈算法)现在交换哨兵i和哨兵j所指向的元素的值。交换之后的序列如下:
6 1 2 5 9 3 4 7 10 8
02
(图源啊哈算法)
到此,第一次交换结束。接下来哨兵继续向左挪动。它发现了4之后停了下来。哨兵i也继续向右挪动,它发现9之后停了下来。此时再次进行交换,再次进行交换,交换之后的序列如下:
(图源啊哈算法)
6 1 2 5 4 3 9 7 10 8
03
第二次交换结束,探测继续。哨兵j继续向左挪动,它发现了3之后又停了下来。此时哨兵i和哨兵j相遇了,哨兵i和哨兵j都走到3面前。说明此时探测结束。我们将基准数6和3进行交换。交换之后的序列如下。
(图源啊哈算法)
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;}
往期推荐
🔗带你图解排序算法之——冒泡排序算法(一)