C C++最全基于Partition函数实现快排、超过一半数字、最小K个数(1),2024年最新C C++学习笔记在互联网上火了

img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上C C++开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

int Partition(vector &nums, int begin, int end)
{
int pivot = nums[begin];//第一个记录作为枢轴(也可是在begin和end之间的随机数)
while (begin < end)
{
while (begin < end && nums[end] >= pivot)
{
end–;
}
nums[begin] = nums[end];//尾部找到小于pivot的值,移到低端

    while (begin < end && nums[begin] <= pivot)

{
begin++;
}
nums[end] = nums[begin];//头部找到大于pivot的值,移到高端
}

nums[begin] = pivot;//枢轴基准归位

return begin;

}


**注意**:这里访问了end值,此时若快排,end=最大下标n-1。


算法分析   
 直观上来看,赋值操作的次数不多,比前面单向扫描的swap次数都少,效率应该会更高。




---


##### 二、二分Partition函数的应用


**快速排序算法**   
 经典的快速排序算法,直接上代码:



void quickSort(vector &nums, int begin, int end)
{

if (begin >= end) return;

int index = partition(nums, begin, end);
if (index>begin)
    quickSort(nums, begin, index-1);
if (index<end)
    quickSort(nums, index+1, end);

}
调用:
quickSort(vec, 0, vec.size()-1); //end为n-1


**数组中出现次数超过一半的数字**   
 **数组的特性** :数组中有一个数字出现的次数超过了数组长度的一半。如果我把这个数组排序,那么排序之后位于数组中间的数字一定就是那个出现次数超过数组一半的数字。也就是说,这个数字就是统计学上的中位数,即长度为n的数组中第n/2的数字。 我们有成熟的O(n)的算法得到数组中任意第K大的数字 。   
 这种算法是受快速排序算法的启发。在随机快速排序算法中,我们现在数组中随机选择一个数字,然后调整数组中数字的顺序,使得比选中的数字小的数字都排在它的左边,比选中的数字大的数字都排在它的右边。如果这个选中的数字的下标刚好是n/2,那么这个数字就是数组的**中位数**。如果它的下标大于n/2,那么中位数应该位于它的左边,我们可以接着在它的左边部分的数组中查找。如果它的下标小于n/2,那么中位数应该位于它的右边,我们可以接着在它的右边部分的数组中查找。这是一个典型的递归过程,实现代码如下:



int MoreThanHalfNum_Solution(vector numbers)
{
int length = numbers.size();
if (numbers.empty() || length<0)
return 0;

int begin = 0;
int end = length - 1;
int middle = length >> 1;
int index = 0; 
//利用
while (begin<end)
{
    index = Partition(numbers, begin, end);
    if (index == middle)
    {
        break;
    }
    else if (index > middle)
    {
        end = index - 1; //则值在左边部分的数组。
    }
    else
    {
        begin = index + 1;//则值在右边部分的数组。
    }
}
//检查该值是否超过数组长度的一半
int cnt = 0;
for (int i = 0; i < length; ++i)
{
    if (numbers[index] == numbers[i])
        cnt++;
}
if (cnt * 2 > length) return numbers[index];

return 0;

}


**最小的K个数**   
 基于数组的第k个数字来调整,使得比第k个数字小的所有数字都位于数组的左边,比第k个数字大的所有数字都位于数组的右边。调整之后,位于数组左边的k个数字就是最小的k个数字(这k个数字不一定是排序的)。时间复杂度O(N)



int Partition(vector &nums, int begin, int end)
{
int pivot = nums[begin];//第一个记录作为枢轴(也可是在begin和end之间的随机数)
while (begin < end)
{
while (begin < end && nums[end] >= pivot)
{
end–;
}
nums[begin] = nums[end];//尾部找到小于pivot的值,移到低端

    while (begin < end && nums[begin] <= pivot)
    {
        begin++;
    }
    nums[end] = nums[begin];//头部找到大于pivot的值,移到高端
}

nums[begin] = pivot;//枢轴基准归位

return begin;

}

vector GetLeastNumbers_Solution(vector input, int k) {

int len=input.size();
if(len==0||k>len ||k<0) return vector<int>();
if(len==k) return input;

int start=0;
int end=len-1;
int index=Partition(input,start,end);
while(index!=(k-1))
{
    if(index>k-1)
    {
        end=index-1;
        index=Partition(input,start,end);
    }
    else
    {
        start=index+1;
        index=Partition(input,start,end);
    }
}

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值