欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 旅游 > 数据结构 ——— 快速排序算法的实现(hoare版本)

数据结构 ——— 快速排序算法的实现(hoare版本)

2024/11/30 6:48:48 来源:https://blog.csdn.net/weixin_55341642/article/details/143968168  浏览:    关键词:数据结构 ——— 快速排序算法的实现(hoare版本)

目录

快速排序的思想

单趟排序逻辑的实现

快速排序算法的实现


快速排序的思想

任取待排序元素序列中的某元素作为基准值,按照该排序码将待排序集合分割成两子序列,左子列中所有元素均小于基准值,右子席列中所有元素均大于基准值,然后最左右子席列重复该过程,直到所有元素都排列在相应位置上为止

选出一个中间值 key,以升序举例,每一趟排序要保证 key 左边的元素比 key 小,key 右边的元素比 key 大,因为这样的话,key 停留的位置就是最后排好序的位置,就不用动了
然后比 key 小的区间再选出一个中间值 key,同样要保证 key 左边的元素比 key 小,key 右边的元素比 key 大;比 key 大的区间也是一样的操作
此操作类似于递归、分治的想法,直到最后 key 的左右两边只有一个数,且同样保证 key 比左大,比右小,那么数组就是升序了


单趟排序逻辑的实现

代码演示:

void Swap(int* p1, int* p2)
{int tmp = *p1;*p1 = *p2;*p2 = tmp;
}int PartSort_Hoare(int* a, int left, int right)
{int key = left;while (left < right){// 先找右边比 key 小的元素的下标while (left < right && a[right] >= a[key])right--;// 再找左边比 key 大的元素的下标while (left < right && a[left] <= a[key])left++;// 交换 Swap(&a[left], &a[right]);}// 把 key 放在最终位置Swap(&a[key], &a[left]);return left;
}

代码解析:

通过以上每一趟排序的递归分治思想来看,left 和 right 并不是从数组的首尾开始递增递减的,而是每次从某一区间开始的

通常中间值的选取是最左边的值,那么 key 就是最左边值的下标
right 找比 key 小的元素,left 找比 key 大的元素
且要注意越界,因为在极端情况下,可能 key 的值小于或者大于任何一个元素
在 key 左边找到了比 key 大的值,在 key 右边找到了比 key 小的值,就进行交换
直到 left 和 right 相遇就停止,因为此时的 left 和right 都指向了同一个元素,没有可交换的

再把 key 放在最终位置,因为最开始 a[key] 是最左边的元素,那么当 while 循环走完时
left 和 right 同时指向的位置就是 a[key] 最终改放的位置

此时就完成了 a[key] 左边的元素比 a[key] 小,a[key] 右边的元素比 a[key] 大,且 a[key] 也放在了最终一个停留的位置

最后再把中间元素的下标 key 进行返回,为什么要返回下面会讲解到


快速排序算法的实现

代码演示:

void QuickSort(int* a, int begin, int end)
{if (begin >= end){return;}int key = PartSort_Hoare(a, begin, end);// [begin,key-1] key [key+1,end]QuickSort(a, begin, key - 1);QuickSort(a, key + 1, end);
}

代码解析:

当 begin 等于 end 时,说明此区间只有一个元素了,那么就不用再递归
当 begin 大于 end 时,说明此区间不存在,同样也停止递归

以上就是递归结束的条件

先通过每一趟的算法函数对数组进行排序,排好后返回了中间元素的下标 key
此时数组 a[key] 左边的值小于等于 a[key],且 a[key] 右边的值大于等于 a[key]

再通过分治的思想进行递归,也就是 [begin,key-1] 这个区间再次排序,且 [key+1,end] 这一区间再次排序,同时配合递归的结束条件,最终完成对数组的排序

代码验证:

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com