C语言——用 堆 实现求N个数中第K大的数

问题描述:

在N(0<N<100000)个数中,找出第K(0<k<100000)大的数。

例如:1,2,3,4,5,6,7,8,9 中第3大的数为 7。

输入:

输入有多组数据,处理到文件结束。

每组数据有两行,

第一行包括两个数,一个正整数N和一个正整数K,

第二行有N个正整数。

输出:

对于每组数据,输出一个数,表示第K大的数,并换行。

样例输入:

12 5
12 4 5 98 4 7 32 1 65 0 65 55 999

10 3

1 2 3 4 5 6 7 8 9 10

样例输出:

32

8

本题的思路可以是用数据结构中的堆来处理,时间复杂度为O(N*logK),

只需要建立大小为K的最小堆,堆顶就是第K大的数。

举个例子:假设N为10,K为3。第一步选取任意3个数,比如前3个,将这3个数建成最小的堆,

然后从第4个数开始,与堆顶的数比较,如果比堆顶的数小,那么这个数就不要,如果比堆顶的数要大,

则舍弃当前堆顶而将这个数作为新的堆顶,并在去维护堆,用同样的方法处理第5~10个数。

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <queue>
#include <stack>
#include <set>
#include <ctype.h>//isalpha,isdight,toupper
#include <map>
#include <sstream>
typedef long long ll;
using namespace std;
#define inf 0x3f3f3f3f
const int maxn=101;

int h[100000],n;

void swap1(int a, int b)
{
    int t;
    t = h[a];
    h[a] = h[b];
    h[b] = t;
}

void siftdown(int i)
{
    int t, flag = 0;
    while(2*i <= n && flag == 0)
    {
        if(h[i] > h[2*i])
        {
            t = 2*i;
        }
        else
        {
            t = i;
        }

        if(2*i + 1 <= n)
        {
            if(h[t] > h[2*i + 1])
            {
                t = 2*i + 1;
            }
        }
        if(t != i)
        {
            swap1(i, t);
            i = t;
        }
        else
        {
            flag = 1;
        }
    }
}

void creat()
{
    for(int i = n/2; i >= 1; i--)
    {
        siftdown(i);
    }
}

int main()
{
    int num, maxi, a[100000];
    while(scanf("%d %d", &num, &maxi) != EOF)
    {
        n = maxi;
        for(int i = 1; i <= num; i++)
        {
            scanf("%d", &a[i]);
            h[i] = a[i];
        }

        creat();

        for(int i = n + 1; i <= num; i++)
        {
            if(a[i] > h[1])
            {
                h[1] = a[i];
                siftdown(1);
            }
            else
            {
                continue;
            }
        }
        printf("%d\n", h[1]);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/abc1235454/article/details/88928249
今日推荐