快速排序 - 非递归实现总结

本文深入探讨快速排序的递归与非递归实现,详细解析了使用递归方法的快速排序算法,并介绍了如何利用栈来实现非递归版本的快速排序,附带Python代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

秋招过去好久了,闲来无事,突然想到一个问题,就是他们总喜欢问快排,当然快排应该是比较简单的啦。当你实现的时候,他们大多会问,非递归的实现,这个就会难到一部分同学哈,我也是。现在总结一下。

快速排序递归实现:

先看一下,这个《数据结构教程》李春葆 第5版,提供的代码(语言是C/C++),递归版的(简练),原理就不解释了:

void QuickSort(RecType R[]int s,int t)
{//对R[s]至R[t]的元素进行快速排序
    int i=s,j=t;
    RecType tmp;
    if (s<t)         //区间内至少存在2个元素的情况
    {
        tmp=R[s];	 //用区间的第1个记录作为基准
        while (i!=j) //两端交替向中间扫描,直至i=j为止
        {
            while (j>i && R[j].key>=tmp.key)
                j--;
            R[i]=R[j];
            while (i<j && R[i].key<=tmp.key)
                i++;
            R[j]=R[i];
        }
        R[i]=tmp;
        QuickSort(R,s,i-1);   //对左区间递归排序
        QuickSort(R,i+1,t);   //对右区间递归排序
    }
    //递归出口:不需要任何操作
}

Python 递归版本:

# @Time   :2023/09/10
# @Author :Liu
# 快速排序 递归

def QuickSort(nums, left, right):

    if left >= right:  # 区间内至少存在2个元素的情况
        return

    i, j = left, right
    pivot = nums[i]	 # 用区间的第1个记录作为基准
    while i != j:  # 两端交替向中间扫描,直至i=j为止
        while j > i and nums[j] >= pivot:
            j -= 1
        nums[i] = nums[j]
        while i < j and nums[i] <= pivot:
            i += 1
        nums[j] = nums[i]

    nums[i] = pivot
    QuickSort(nums, left, i-1)  # 对左区间递归排序
    QuickSort(nums, i+1, right)  # 对右区间递归排序


if __name__ == '__main__':
    nums = [10, 7, 8, 9, 1, 5, 11]
    n = len(nums)
    QuickSort(nums, 0, n - 1)
    print(nums)
快速排序非递归的实现:

现在重点介绍一下非递归的方法,很显然,需要借助栈来实现。具体原理如下:

(1)我们找一个基准进行一趟快排,一般会产生两个区间,这时,可以用一个栈保存这两个区间(区间类型[start, end])。很显然,现在已经归位一个元素了。
(2)循环判断栈,出栈,也就是拿出一个区间,继续一趟快排,再归位一个元素然后再判断产生的区间入栈
(3)直到栈为空,此时已经说明列表,排序好了。

Python实现代码:

# @Time   :2019/01/21
# @Author :LiuYinxing
# 快速排序 栈


def QuickSort(arr):  # 模拟栈操作实现非递归的快速排序

    if len(arr) < 2:return arr

    stack = []
    stack.append([0, len(arr)-1])  # 初始化栈

    while stack:
        l, r = stack.pop()  # 出栈一个区间
        index = partition(arr, l, r)  # 对分区进行一趟交换操作,并返回基准线下标
        if l < index - 1:
            stack.append([l, index - 1])  # 当前趟,左区间入栈
        if r > index + 1:
            stack.append([index + 1, r])  # 当前趟,右区间入栈


def partition(arr, s, t):  # 对分区进行一趟交换操作,并返回基准线下标

    tmp = arr[s]  # 用区间的第1个记录作为基准
    while s < t:
        while s < t and arr[t] >= tmp: t -= 1
        arr[s] = arr[t]
        while s < t and arr[s] <= tmp: s += 1
        arr[t] = arr[s]
    # 此时s = t
    arr[s] = tmp
    return s


if __name__ == '__main__':
    arr = [4, 5, 0, -2, -3, 1]
    QuickSort(arr)
    print(arr)

声明: 总结学习,有问题或不当之处,可以批评指正哦,谢谢。

[1] 非递归代码参考链接

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值