Python实现原地Quicksort快速排序的代码存在什么错误?
你的Quicksort实现存在的核心问题
代码无法得到正确排序结果,主要是2个关键逻辑错误:
- 递归传参使用列表切片,导致原地修改完全失效
Python中列表切片操作b[:i-1]、b[i:]会生成原列表的浅拷贝新对象,递归调用时传入的是这些独立的新列表,递归过程中的所有交换操作都只修改临时副本,根本不会同步到最开始传入的原始列表,最后打印原列表时只会保留第一次分区的改动,后续递归排序的结果全部丢失。 - 分区循环遍历范围不合理
已经选择首元素b[0]作为基准值p,循环j从索引0开始遍历属于无意义操作,虽然当前逻辑下j=0时b[j] == p不会触发交换,但如果后续调整基准值选取位置,很容易触发基准值被提前交换的bug,正确的遍历范围应该从j=1开始。
修正后的原地快排实现
原地快排的标准实现是通过传入左右边界索引来操作同一份原列表,不需要生成切片副本,参考代码如下:
def quicksort(b, left=0, right=None): # 初始化右边界 if right is None: right = len(b) - 1 # 递归终止条件:区间长度小于等于1 if left >= right: return p = b[left] # 选左端点为基准 i = left + 1 for j in range(left + 1, right + 1): if b[j] < p: b[j], b[i] = b[i], b[j] i += 1 # 把基准值交换到正确的分界位置 b[left], b[i-1] = b[i-1], b[left] # 递归排序左右区间,直接操作原列表的索引范围,不生成切片 quicksort(b, left, i-2) quicksort(b, i, right) b = [3,1,7,2,6,5,9] quicksort(b) print(b) # 输出 [1, 2, 3, 5, 6, 7, 9]
注:修正后全程操作同一个列表对象,通过左右索引标记待排序区间,完全符合原地排序的逻辑,不会出现修改不同步的问题。
内容的提问来源于stack exchange,提问作者v1998199904
相关产品推荐
相关产品推荐

