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

如何使Java实现的快速排序(Quicksort)算法稳定?技术求助

稳定快速排序的实现方案

普通原地快速排序无法保持稳定性的核心原因是:分区过程中的交换操作会打乱相等元素的相对位置。比如当pivot是某个相等元素时,交换可能导致原本在前面的相等元素被移到后面,破坏相对顺序。

要实现稳定的快速排序,我们可以通过额外空间分区的方式,将数组拆分为小于、等于、大于pivot的三个部分,保留等于pivot元素的原始顺序,再合并后递归排序左右部分。以下是具体实现:

@Override
public void quickSortStable(Integer[] data) {
    if (data == null || data.length <= 1) {
        return;
    }
    quickSortStable(data, 0, data.length - 1);
}

private static void quickSortStable(Integer[] data, int start, int end) {
    if (start >= end) {
        return;
    }
    // 分区后得到等于pivot元素的左右边界
    int[] bounds = partitionStable(data, start, end);
    // 递归排序小于pivot的区域和大于pivot的区域
    quickSortStable(data, start, bounds[0] - 1);
    quickSortStable(data, bounds[1] + 1, end);
}

private static int[] partitionStable(Integer[] data, int start, int end) {
    int pivot = data[end];
    // 分别存放小于、等于、大于pivot的元素,保留原始顺序
    List<Integer> less = new ArrayList<>();
    List<Integer> equal = new ArrayList<>();
    List<Integer> greater = new ArrayList<>();

    for (int i = start; i <= end; i++) {
        if (data[i] < pivot) {
            less.add(data[i]);
        } else if (data[i] == pivot) {
            equal.add(data[i]);
        } else {
            greater.add(data[i]);
        }
    }

    // 将元素放回原数组
    int index = start;
    for (int num : less) {
        data[index++] = num;
    }
    int leftEqualBound = index;
    for (int num : equal) {
        data[index++] = num;
    }
    int rightEqualBound = index - 1;
    for (int num : greater) {
        data[index++] = num;
    }

    return new int[]{leftEqualBound, rightEqualBound};
}

关键说明

  • 稳定性保证:遍历原数组时,等于pivot的元素会按原始出现顺序加入equal列表,再写回原数组,因此相等元素的相对顺序完全保留。
  • 空间代价:这种实现需要O(n)的额外空间来存放三个子列表,这是实现稳定快速排序的必要权衡——原地交换的快速排序无法避免相等元素的顺序打乱。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 20:50:12