快排之第k大数

学习目标:快速排序之第k大数

从今天开始搞算法,一天一个,第二天,强行flag


学习内容:

  • 对于数组,借用快排的轴判断,k位于哪个区间
  • 对此区间数组进行重复操作
  • 退出条件为begin==end

学习时间:

提示:大概用时
1、 21/2/23周一 晚上 7 点—晚上9点


kthLargest code:

#include<stdio.h>
#include <stdlib.h>
#include <time.h>
void swap(int arr[],int j,int k)
{
    if(j==k) return;    // 同一元素时则不交换
    int temp;
    temp=arr[j];
    arr[j]=arr[k];
    arr[k]=temp;
    printf("swap %d and %d\n",arr[j],arr[k]);
}

int randompartition(int arr[],int begin,int end)
{
    int a;
    srand((unsigned)time(NULL));
    a = rand()%(end-begin)+begin;
    //printf(" a=%d ",a);
    swap(arr,a,begin);//除去以上即为正常快速排序

    int first = arr[begin];
    int i = begin+1,p=begin;
    for(i;i<=end;i++)
    {
        if(first<arr[i])    // 逆序 从大到小
        {
            p++;
            swap(arr,p,i);
        }
    }
    swap(arr,p,begin);
    printf("one time %d \n",p);
    return p;
}
// 第k大数,是从大到小排序后,正数第k个数
int randomselect(int arr[],int begin,int end,int aim)
{
    int i,j;
    if(begin==end) return arr[begin];
    i = randompartition(arr,begin,end);
    j=i-begin+1;    // 得到以轴分开的数组左侧长度,判断左侧长度(含轴)与目标位置aim是否包含,舍弃另一半
    if(aim>j) 
    	randomselect(arr,i+1,end,aim-j);
    else 
    	randomselect(arr,begin,i,aim);
}

int main()
{
    int Len,i,aim;
    while(scanf("%d",&Len)!=EOF)
    {
        int nums[Len];
        for(i=0;i<Len;i++)
        {
            scanf("%d",&nums[i]);
        }
        scanf("%d",&aim);
        printf("%d\n",randomselect(nums,0,Len-1,aim));
    }
    return 0;
}

最后自己再来总结一下,这个和二分法有异曲同工之妙,但是快排明显随机性更高巧妙性更高,随机选取轴,选取区间,对于区间再快排选取轴,以此来达到选取第k大数,不需要排序是相当舒服了
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值