从partition到Quicksort

本文主要讨论quicksort和寻找第k大元素的两个相关问题。

力扣连接https://leetcode-cn.com/problems/sort-an-array/【排序算法精华3】快速排序 (上)_哔哩哔哩_bilibili"五点七边-算法学习" QQ交流群:539835344快速排序(英语:Quicksort),简称快排,是一种排序算法,最早由东尼·霍尔提出。正如它的名字所暗示的那样,快速排序的最大优点在于它的速度非常快。在实现的比较好的时候,快速排序往往比归并排序、堆排序等优秀的排序算法更快...感谢:本视频动画使用manim数学引擎制作: http://github.com/3b1b/manhttps://www.bilibili.com/video/BV1rV411j7f6?from=search&seid=11355076395128076944&spm_id_from=333.337.0.0

快速排序法的思路是基于分而治之,:将数组不断地一分为二,再去处理更小的部分。但是,当实际写代码时,递归时具体分块的实现函数的实现总是让我难受,在这个函数里会使用到两个指针,一个i,一个j,它们是用来干嘛的呢?

为了回答这个问题,首先要知道partition这个函数用来干嘛,他有两个任务:1.将数组中小于和大于pivot的元素分别放到它的两边;2. 返回pivot的index。针对这个过程,很容易想象,我们需要

1. 实现遍历,其中一个指针的作用就是实现从左到右的完全遍历(没必要遍历pivot)

2. 指向pivot元素应该出现的位置,这是我们需要返回的index

基于这些提示,来尝试实现一下这个函数,这里我们自动选择最右侧元素为每次的pivot元素

void swap(vector<int> &array, int idx1, int idx2) {
  int tmp = array[idx1];
  array[idx1] = array[idx2];
  array[idx2] = tmp;
  return;
}
int partition(vector<int> &array, int l_idx, int r_idx) {

  int i = l_idx, j = l_idx, pivot = r_idx;
  while (j < r_idx) {
    if (array[j] < array[pivot]) {
      swap(array, i, j);
      i++;
    }
    j++;
  }
  swap(array, r_idx, i);
  return i;
}

在实现了partition这个函数后,基于它,接下来快速排序的实现就很容易了,一个简单的递归就可以搞定,

void quickSort(vector<int>& array,int left,int right)
{
    if (right<=left) {return;}
    int q = partition(array, left,right);
    //注意这里index的选择,没有+1或者-1,会让程序陷入死循环。
    quickSort(array,left,q-1);
    quickSort(array,q+1,right);
}

除了实现快速排序,当我们想要寻找第k大的元素时,我们也可以基于partition来实现,同样是递归的思想,唯二不同的是终止条件和少了一半的递归操作。

int getNthLargestNum(vector<int>&array,int k,int left,int right)
{
    int q= partition(array,left,right);
    if(q==array.size()-k) return array[q];
    else if(q<array.size()-k)
    {
        return getNthLargestNum(array,k,q+1,right);
    }
    else
    {
        return  getNthLargestNum(array,k,left,q-1);
    }

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值