数据结构-排序:快速排序的多种实现方法(Hoare,挖坑,双指针,非递归)

本文详细介绍了快速排序的多种实现方式,包括Hoare版本的左闭右闭和左闭右开,挖坑法,前后指针法带三数取中优化,以及非递归的栈和队列实现。通过具体的步骤和示例,阐述了快速排序的核心思想和细节,帮助读者深入理解这一经典排序算法。
摘要由CSDN通过智能技术生成

快速排序是交换排序的一种,这是因为快速排序的核心还是交换两个合适的元素。快排有很多实现方法,类似更新迭代,但是核心思想都一样。Hoare法,挖坑法,前后指针法,非递归法(栈实现,队列实现)  下面一一介绍。

目录

快速排序,Hoare版本:

快速排序,挖坑法:

快速排序,前后指针法,带三数取中等优化:

快速排序非递归(栈实现)

快速排序非递归(队列实现)


快速排序,Hoare版本:

Hoare 左闭右闭

void QuickSort(int* arr, int begin, int end) {  // [begin, end]
    int left = begin;
    int right = end;
    int keyi = begin;  // 设置下标是因为后面要交换数据
    while(left < right) {
        // 右边找小
        while(left < right && arr[right] >= arr[keyi]) {
            right--;
        }
        // 左边找大
        while(left < right && arr[left] <= arr[keyi]) {
            left++;
        }
        // 这里不管是否left<right都交换,等于也无妨。
        swap(arr[left], arr[right]);
    }
    // 这里出循环之后,一定符合left == right。
    swap(arr[keyi],arr[left]);
    // [begin, left-1] left [left+1, end]
    if(left-1>begin)
        QuickSort(arr,begin,left-1);
    if(left+1<end)
        QuickSort(arr,left+1,end);
}

单趟排序目的:找一个key下标的值,单趟排序结束后key的左边比它小,右边比它大,这样为一次单趟排序。

这里暂时先不使用三数取中的优化,先找一个key值(一般为最左边或最右边),这里默认为left下标处的值。然后定义left,right。右边找小于key的值,左边找大于key的值,且必须是right先走。(这里有原因,后序解答)。当右边找到小,左边找到大,交换左右下标的值,使得大值去右边,小值去左边。当left和right相遇之后循环退出,再交换key下标的值,和相遇处的值(这里取left和right都可以) 至此,单趟排序结束。

细节1:右边一定要找小于key的值,左边一定要找大于key的值,也就是while循环中必须为arr[right]>=arr[key]。不可以为arr[right] > arr[key]  为了防止如下情况:5 5 1 2 3 4 5 这样就会陷入死循环。

细节2:每个循环都要写left<right这个条件。而不管在任何一个循环处达到了left=right  都可以正常停下,while里的swap也只是没有意义的交换,然后退出大的while。

为什么key在左边必须右边先走?举例所有情况,你会发现,只有右边先走才可以达成相遇处的值<= arr[key]  情况1:右边去遇到左边:此时left或者为初始的key下标。或者是上一次left right交换之后的left。初始的key说明key右边的所有值都大于等于key下标的值,相遇之后相当于自己交换。而上一次交换之后的left一定小于key。   所以综上情况1的两种可能,都可以达到相遇处的值小于等于arr[key](事实上可能性1的概率很小)  这样交换之后才可以保证key左边的值小于它,右边的值大于他。࿰

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值