三路快速排序

三路快速排序

算法概述

三路快速排序是一种改进的快速排序算法,它将数组分成三个部分:小于枢轴的部分、等于枢轴的部分和大于枢轴的部分。这样可以更高效地处理包含大量重复元素的数组。主要步骤如下:

  1. 选择枢轴:随机选择一个元素作为枢轴。
  2. 分区:将数组分成三部分:
    • 小于枢轴的部分
    • 等于枢轴的部分
    • 大于枢轴的部分
  3. 递归排序:对小于枢轴和大于枢轴的部分分别进行递归排序。

算法实现

package sort

import (
  "math/rand"
)

func QSort(arr []int) {
  qSort(arr, 0, len(arr)-1)
}

func qSort(arr []int, l, r int) {
  if l >= r {
    return
  }
  // 随机生成枢轴下标。
  // 在数组是基本有序的情况下,算法性能会退化,随机选择枢轴可以使快速排序的平均性能更接近理论上的最佳情况。
  pivot := l + rand.Intn(r-l+1)
  // 把枢轴的值先放在序列最左端
  arr[l], arr[pivot] = arr[pivot], arr[l]

  // 待排序序列分成三部分:
  // arr[l + 1, lt] < v:小于枢轴的部分,刚开始是空集;
  // arr[lt + 1, i - 1] == v: 等于枢轴的部分。增加这一部分,能一次把相等的部分归集在一起;
  // arr[gt, r] > v: 大于枢轴的部分,刚开始是空集。
  // 遍历的时候从第二个元素开始。
  lt, i, gt := l, l+1, r+1
  for i < gt {
    if arr[i] < arr[l] {
     // 小于枢轴的部分自左向右扩展了一个元素
     lt++
     // i 一直都 >= lt, 交换元素后,不需要判断 arr[i] 与枢轴的大小,因为已经比较过,需要跳过
     arr[i], arr[lt] = arr[lt], arr[i]
     i++
    } else if arr[i] > arr[l] {
     // 大于枢轴的部分自右向左扩展一个元素
     gt--
     // 交换位置后,需要判断交换后的元素 arr[i] 与枢轴的大小,所以后续不进行 i++, 以免跳过
     arr[i], arr[gt] = arr[gt], arr[i]
    } else {
     i++
   }
 }
  // 把枢轴放到合适的位置
  arr[l], arr[lt] = arr[lt], arr[l]
  // 对小于枢纽的部分进行递归排序
  qSort(arr, l, lt-1)
  // 对大于枢纽的部分进行递归排序
  qSort(arr, gt, r)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值