1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > C语言 史上最详细快速排序图解 让小白也能轻松理解

C语言 史上最详细快速排序图解 让小白也能轻松理解

时间:2021-10-27 13:33:22

相关推荐

C语言 史上最详细快速排序图解 让小白也能轻松理解

快速排序可以看作是冒泡排序的一种升级版,优点就是快速,但是稳定性差。

因为是史上最详细快速排序,所以我写的非常细~~基本每一句代码都解释+图解到位了,需要耐心浏览。

快速排序的功能概括就是在数组中选定一个key值,把小于key的数放在左边,大于key的数放到右边,再对key左边和右边的数分别再选一个key值进行重复操作。

先上代码,再对代码进行图解,大家也可以先把代码跑一遍,有个底…

//快速排序void my_sort(int arr[],int low,int high){//递归结束条件if (low >= high)return;//记录数组第一个值和最后一个值int left = low, right = high;//这里我们把第一个数选作中心值int key = arr[left];while (left < right){while (left < right && arr[right] >= key){right--;}arr[left] = arr[right];while (left < right && arr[left] <= key){left++;}arr[right] = arr[left];}arr[right] = key;my_sort(arr, low, left - 1);my_sort(arr, left + 1, high);}int main(int argc, char *argv[]){int arr[10] = {2,8,6,1,4,3,9,0,7,5 };int len = sizeof(arr) / sizeof(arr[0]);my_sort(arr, 0, len-1);for (int i = 0; i < 10; i++){cout << arr[i] << " ";}cout << endl;system("pause");return 0;}

代码很少,但是得理解到位

函数三个参数void my_sort(int arr[],int low,int high)

//int arr[] 数组首地址

//int low 数组第一个元素位置

//int hight 数组最后一个元素位置

回溯上面代码

第一步

记录数组第一个位置(low)和最后一个位置(high)。

int left = low, right = high;

第二步

选取一个值作为中心值,保存在key中,这里我们选第一个值

int key = arr[left];

此时我们可以看作数组的第一个位置是空出来的(第一个位置的值已经保存到key中了,不用慌~),等待一个从右边数起小于key的值填到第一个位置来。

第三步

从最右边right开始找,找一个小于key的数,找到了便填到空出的位置上(即是left目前所以在的位置),如果找不到说明右边所有的数都比key大,则跳出循环,写代码,当left<right而且arr[right] >= key时,right一直往左边移动

while (left < right && arr[right] >= key){right--;}arr[left] = arr[right];

显然从right开始找起,5和7都比2大,当right移动这个0位置上,while (left < right && arr[right] >= key)这个条件不满足了,于是跳出循环,执行arr[left] = arr[right];如图,把0拷贝到了第一个位置

此时数组时这个样子的

那么接下来该做什么呢,现在我们知道右边right位置上空出来了,所以我们需要从左边找起,

第四步

从left开始找第一个大于key的数,填到右边去,于是写出代码,当left<right而且arr[left]<=key时,left一直往右移动。

while (left < right && arr[left] <= key){left++;}arr[right] = arr[left];

从右边找起,第一个位置上的数已经变成了0,小于key(2),left++,当left移动到8位置上,发现大于key(2),所以while (left < right && arr[left] <= key)条件不满足了 ,跳出循环执行arr[right] = arr[left];如图所示

此时数组变成这样

左边又空出来,所以大家应该知道又得从右边right当前位置接着开始找一个小于key(2)的数填到左边空出来的位置上,所有是重复上面的第三步,当第三步中把左边的数拷贝到右边时,又得重复第四步,于是有

第五步

我们把第三步和第四步的代码再用一个whille循环包起来就有如下代码

while (left < right){while (left < right && arr[right] >= key){right--;}arr[left] = arr[right];while (left < right && arr[left] <= key){left++;}arr[right] = arr[left];}

可能有人会想为什么while中的条件是left < right,因为left是从左边最小的位置开始遍历,right是从右边最大的位置开始遍历,当left=right时,说明找到了同一个数了,已经把所有的数都对比过了,所以此时循环结束。

好了,再结合第一步和第二步,我们的代码就写到这了

void my_sort(int arr[],int low,int high){//第一步int left = low, right = high;//第二步int key = arr[left];//第五步while (left < right){//第三步while (left < right && arr[right] >= key){right--;}arr[left] = arr[right];//第四步while (left < right && arr[left] <= key){left++;}arr[right] = arr[left];}}

于是在第五步循环中再执行第三步的操作,从right开始找到1的位置是小于key的

数组变成这样

右边又空出来了,执行第四步找到6是大于key的,则有

数组变成

此时所有的数都已经遍历完了,再移动一次left和right便会相等,我们就不需要再比较了,就有为什么上面while循环的结束条件是left<right,所以当跳出循环时则表示,left=right

现在发现还有一个位置是空出来的 ,于是我们得把这个位置再填上,

那么用哪个值填呢,没错,就是最开始拿出来的中心值key,你会发现这个位置左边的值都小于key,右边的值都大于key,这也是写这个代码的目的,于是有

第六步

arr[right] = key;//也可写成arr[left] = key;因为此时left和right是相等的

这样我们的第一轮排序便完成了,数组此时的排序是这样的

第七步

最后便是完成递归操作

my_sort(arr, low, left - 1);my_sort(arr, left + 1, high);

对上一个中心值的两边再进行第一步到第七步的重复动作,我们把0 1扔到my_sort里面再排序一便,把6 4 3 9 8 7 5仍到my_sort里面也排序一遍,重复这个操作,这个便是递归,如果有同学对递归有疑问的,可以留言,我再写一篇史上最详细递归解析~

如图

于是整套代码解释完毕,最后补上前两行的递归结束条件,写递归函数一定要注意写结束条件,否则陷入死循环了,已经看到这的同学,至于递归条件为什么是low >= high,相信大家应该没问题了吧。

void my_sort(int arr[],int low,int high){//递归结束条件if (low >= high)return;//第一步int left = low, right = high;//第二步int key = arr[left];//第五步while (left < right){//第三步while (left < right && arr[right] >= key){right--;}arr[left] = arr[right];//第四步while (left < right && arr[left] <= key){left++;}arr[right] = arr[left];}//第六步arr[right] = key;//也可写成arr[left] = key;因为此时left和right是相等的//第七步my_sort(arr, low, left - 1);my_sort(arr, left + 1, high);}

最后大家如果看懂了的话,回顾上面第三步和第四步的图中,我所画的空出来的位置,并不是那个位置上的数真的被清空了,而是为了方便让大家理解,数组上的数还是存在的,只是我们要往那个位置上填一个比key值大或者比key值小的数。

如有疑问,欢迎大家踊跃留言,最后点一个赞呗~

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。