Partition算法详解

partition算法有着非常重要的应用,这个算法的思想虽然简单,但具体实现的细节却比较多,今天我重点复习了这个算法,本文记录我对这个算法的理解。

Partition算法解析

二分Partition

快速排序作为非常著名的排序算法,其思想却很简单:每次从数组中选一个数作为pivot,然后将数组划分为2部分,小于等于pivot数的在其左边,大于等于pivot的数在其右边,然后分别对pivot的左边和右边进行递归。
二分partition的实现用到了双指针,left寻找一个比pivot大的数,right寻找一个比pivot小的数,然后交换它们,循环这一过程直到left == right,将pivot放到这个位置。
注意: 如果pivot选的是最左的元素,则要先移动right;如果pivot选的是最右的元素,则要先移动left。

int partition(vector<int>& nums, int left, int right) {
   
    int pivot = nums[left], base = left;
    while (left < right) {
   
        while (left < right && nums[right] >= pivot) right--;
        while (left < right && nums[left] <= pivot) left++;
        swap(nums[left], nums[right]);
    }
    nums[base] = nums[left];
    nums[left] = pivot;
    return left;
}
三分Partition

三分partition自然就是把数组划分成3部分,小于pivot的在左边,等于pivot的在中间,大于pivot的在右边。
由于三分partition要保证中间的那部分,所以像二分partition那么划分是肯定不行的。为了解决这个问题,我们需要先定义循环不变量

  • [0, zero)内的元素都等于0
  • [zero, curr)内的元素都等于1
  • [curr, two]内的元素还未被检查
  • (two, len - 1]内的元素都等于2

我们用curr来遍历数组,遍历的范围是[0, two]。在整个遍历过程中,始终要保证循环不变

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值