快速排序实现问题:分区时基准元素的包含与排除
QuickSort基准元素分区的常见问题分析
我在实现QuickSort时,遇到了基准元素(pivot)分区包含/排除相关的三个问题,逐一分析如下:
第一种实现报错终止:把基准元素包含进left列表,函数末尾没单独添加。
本质是触发了无限递归。当基准元素被放进left子数组,递归处理left时,这个元素会再次被选为pivot,导致子数组永远包含该元素,无法触发递归终止条件(子数组长度为0或1),最终栈溢出,VS Code因此报错停止。第二种实现丢失重复项:将基准元素从left中排除,最后单独添加。
问题出在分区逻辑——如果分区时把所有等于pivot的元素都排除在left和right之外,仅保留单独的pivot,那原数组中重复的pivot元素会被直接丢弃。比如原数组有多个和pivot相等的元素,这些元素既没进入left也没进入right,最后只拼接了一个pivot,自然丢失了重复项。第三种实现正常排序,为何和第一种差异明显?
看似两者都只包含一次基准元素,但核心区别是分区后的子数组是否还保留当前pivot:
第一种是把pivot直接混入left,递归时会重复处理它;而第三种的分区逻辑应该是:选完pivot后,left只存小于pivot的元素,right存大于(或大于等于)pivot的元素,或者先把pivot从原数组移除再分区,递归处理完left和right后,再把pivot插在中间。这种情况下,子数组里不再包含当前pivot,递归能正常收敛到终止条件,不会出现无限递归。
内容的提问来源于stack exchange,提问作者Dmitr Egorov
相关产品推荐
相关产品推荐

