快速排序算法递归失效问题:列表浅拷贝困惑及无库解决方案
快速排序递归失效问题的解决办法
你的问题核心是切片操作创建了列表副本: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
相关产品推荐
相关产品推荐

