You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

快速排序算法递归失效问题:列表浅拷贝困惑及无库解决方案

快速排序递归失效问题的解决办法

你的问题核心是切片操作创建了列表副本:numbers[:i]和numbers[i+1:]会生成原列表的子列表副本,递归调用时修改的是这些副本,而非原列表本身,所以原列表的子区间无法被正确排序。

下面提供两种无需导入库的解决方式:

方式一:通过索引操作原列表(原地排序)

这种方式直接在原列表的指定区间内操作,不创建副本,效率更高:

def quicksort(numbers: list):
    def _quicksort(left, right):
        if left >= right:
            return
        # 选取右边界元素作为基准
        pivot = numbers[right]
        i, j = left, right - 1
        while True:
            # 找到左侧大于基准的元素
            while i <= j and numbers[i] <= pivot:
                i += 1
            # 找到右侧小于基准的元素
            while i <= j and numbers[j] >= pivot:
                j -= 1
            if i > j:
                break
            # 交换左右元素
            numbers[i], numbers[j] = numbers[j], numbers[i]
        # 将基准元素放到正确位置
        numbers[i], numbers[right] = numbers[right], numbers[i]
        # 递归处理左右子区间
        _quicksort(left, i - 1)
        _quicksort(i + 1, right)
    
    _quicksort(0, len(numbers) - 1)
    return numbers

说明:内部函数_quicksort通过left和right参数限定操作区间,所有修改直接作用于原列表,递归调用时也操作原列表的对应区间,最终完成原地排序。

方式二:合并递归结果(非原地排序)

如果希望保持函数的纯函数特性(不修改输入列表),可以将递归排序后的子列表与基准元素合并,返回新的排序列表:

def quicksort(numbers: list):
    if len(numbers) <= 1:
        return numbers
    pivot = numbers[-1]
    i, j = 0, len(numbers) - 2
    while True:
        while i <= j and numbers[i] <= pivot:
            i += 1
        while i <= j and numbers[j] >= pivot:
            j -= 1
        if i > j:
            break
        numbers[i], numbers[j] = numbers[j], numbers[i]
    # 将基准元素放到正确位置
    numbers[i], numbers[-1] = numbers[-1], numbers[i]
    # 递归排序左右子列表并合并结果
    left_sorted = quicksort(numbers[:i])
    right_sorted = quicksort(numbers[i+1:])
    return left_sorted + [numbers[i]] + right_sorted

说明:每次递归都会返回排序后的子列表,最后将左子列表、基准元素、右子列表拼接成完整的排序列表。

内容的提问来源于stack exchange,提问作者maolmedilla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 16:01:00