堆有关的面试题(后续补充)

//*********************************************************
//面试题:N个数找出最大的前K个(N超级大)
//
//思路:用前K个数建个小堆,然后向后遍历其余数,凡是遇到比堆根节点大的,
//      就替换根节点,然后向下调整,使之始终保持小堆,然后继续遍历,
//      直至访问完数据。这样就将前K个大的数据全放在了堆中。
//
//时间复杂度:建堆+遍历(KlgK+(N-K)lgN) ->NlgK
//*********************************************************

#include<iostream>
#include<algorithm>
#include<functional>

using namespace std;

const int N = 10000;
const int K = 10;

void AdjustDown(int* a)   //向下调整
{
    int father = 0;
    int child = (a[father * 2 + 1] < a[father * 2 + 2] ? (father * 2 + 1) : (father * 2 + 2));
    while (a[father] > a[child] && child < K)
    {
        swap(a[father], a[child]);
        father = child;
        if (father * 2 + 1 == K - 1)
            child = father * 2 + 1;
        if(father*2+1 < K-1)
            child = (a[father * 2 + 1] < a[father * 2 + 2] ? (father * 2 + 1) : (father * 2 + 2));
    }
}


int main()
{
    int a[N] = { 0 };
    for (int i = 0; i < N; ++i)
    {
        a[i] = rand()%100;  //赋值为小于100的随机值
    }

    a[54] = 111;
    a[542] = 122;
    a[2] = 3124;
    a[393] = 999;
    a[333] = 888;
    a[1001] = 789;
    a[3214] = 1131;
    a[3245] = 1115;
    a[3924] = 911;
    a[112] = 112;

    make_heap(a, a+K,greater<int>());  //建小堆
    cout << "make_heap:" << endl;
    for (int i = 0; i < K; ++i)
    {
        cout << a[i] << " ";
    }
    cout << endl;

    for (int i = K; i < N; ++i)
    {
        if (a[i] >= a[0])
        {
            a[0] = a[i];
            AdjustDown(&a[0]);
        }
    }
    cout << "make_heap:" << endl;
    for (int i = 0; i < K; ++i)
    {
        cout << a[i] << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

这里写图片描述

//////////////////////////////////////////////////////////
//堆排序(选择排序的一种)
//
//思路:1,升序:先建一个大堆(0,n-1),然后将堆顶节点(值最大的节点)
//               与堆最后一个节点交换,然后就形成了两部分:有序区
//              (n-1)和 无序区(0,n-2),然后将无序区调整为堆,循环
//               以上步骤,直至最后一个节点
//      2,降序:建一个小堆,其余和升序本质一样。
//
//时间复杂度:N*logN
///////////////////////////////////////////////////////////

//升序
void HeadSort(int* a, size_t n)
{
    for (int i = n; i > 0; i--)
    {
        make_heap(a, a+i);    //建大堆
        swap(a[0], a[i - 1]);   //交换堆顶节点与堆尾节点
    }
}


int main()
{
    int a[10] = { 0 };
    for (int i = 0; i < 10; ++i)
    {
        a[i] = 10 - i;
    }

    HeadSort(a, 10);

    for (int i = 0; i < 10; ++i)
    {
        cout << a[i] << " ";
    }
    cout << endl;

    system("pause");
    return 0;
}

这里写图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值