Java 三路快排

打印 上一主题 下一主题

主题 1016|帖子 1016|积分 3048

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

x
三路快速排序(3-Way QuickSort)是快速排序的优化版本,特别适用于处理包罗大量重复元素的数组。其核心思想是将数组分别为三个区域:小于基准值等于基准值大于基准值,从而减少不须要的递归和互换
三路快排原理


  • 分区逻辑

    • 使用三个指针 lt(less than)、current(当前遍历位置)、gt(greater than)将数组分别为三部分:

      • [low, lt-1]:小于基准值的元素
      • [lt, gt]:等于基准值的元素
      • [gt+1, high]:大于基准值的元素

    • 通过一次遍历,将元素分配到正确区域。

  • 时间复杂度

    • 均匀:O(n log n)
    • 最坏(大量重复元素时):O(n)(优于传统快排的 O(n²))

Java 实现代码

  1. public class ThreeWayQuickSort {
  2.     public static void sort(int[] arr) {
  3.         if (arr == null || arr.length <= 1) return;
  4.         threeWayQuickSort(arr, 0, arr.length - 1);
  5.     }
  6.     private static void threeWayQuickSort(int[] arr, int low, int high) {
  7.         if (low >= high) return;
  8.         // 选择基准值(这里选第一个元素)
  9.         int pivot = arr[low];
  10.         int lt = low;      // 小于 pivot 的右边界
  11.         int gt = high;     // 大于 pivot 的左边界
  12.         int current = low; // 当前遍历指针
  13.         while (current <= gt) {
  14.             if (arr[current] < pivot) {
  15.                 swap(arr, lt, current);
  16.                 lt++;
  17.                 current++;
  18.             } else if (arr[current] > pivot) {
  19.                 swap(arr, current, gt);
  20.                 gt--;
  21.             } else {
  22.                 current++;
  23.             }
  24.         }
  25.         // 递归处理小于和大于区域
  26.         threeWayQuickSort(arr, low, lt - 1);
  27.         threeWayQuickSort(arr, gt + 1, high);
  28.     }
  29.     private static void swap(int[] arr, int i, int j) {
  30.         int temp = arr[i];
  31.         arr[i] = arr[j];
  32.         arr[j] = temp;
  33.     }
  34.     public static void main(String[] args) {
  35.         int[] arr = {3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5};
  36.         sort(arr);
  37.         System.out.println(Arrays.toString(arr));
  38.         // 输出: [1, 1, 2, 3, 3, 4, 5, 5, 5, 6, 9]
  39.     }
  40. }
复制代码
关键步调解析


  • 初始化指针

    • lt 指向数组起始位置(low),gt 指向数组末尾(high),current 从 low 开始遍历。

  • 遍历与互换

    • 如果 arr[current] < pivot:将 current 与 lt 处的元素互换,lt 和 current 均右移。
    • 如果 arr[current] > pivot:将 current 与 gt 处的元素互换,gt 左移(current 不移动,因为互换后的新元素需要再次查抄)。
    • 如果 arr[current] == pivot:直接移动 current 指针。

  • 递归处理子数组

    • 对 [low, lt-1](小于区域)和 [gt+1, high](大于区域)递归排序,中间区域 [lt, gt] 已经有序。


示例流程

假设初始数组为 [3, 1, 4, 1, 5, 9, 2, 6, 5, 3, 5],基准值 pivot=3:

  • 第一次分区后

    • 小于区域:[1, 1, 2]
    • 等于区域:[3, 3]
    • 大于区域:[4, 5, 9, 6, 5, 5]

  • 递归排序小于区域 [1, 1, 2] 和大于区域 [4, 5, 9, 6, 5, 5]。

上风与适用场景



  • 上风

    • 高效处理重复元素,避免传统快排的重复递归。
    • 减少元素互换次数。

  • 适用场景

    • 数组中存在大量重复元素(如日志数据、用户行为数据)。
    • 需要稳固排序但允许非稳固实现的情况。


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

慢吞云雾缓吐愁

论坛元老
这个人很懒什么都没写!
快速回复 返回顶部 返回列表