堆的应用

  1. 优先级队列

      优先级队列(priority queue) 是0个或多个元素的集合,每个元素都有一个优先权,对优先级队列执行的操作有查找,插入一个新元素 ,删除。 一般情况下,查找操作用来搜索优先权最大的元素,删除操作用来删除该元素 。对于优先权相同的元素,可按先进先出次序处理或按任意优先权进行。

     下面我们用堆来实现优先级队列(这里就不再实现堆了,堆的实现请看上一篇博文

template<class T>
class PariorityQueue
{
public:
    PariorityQueue()
    {}      
    void Push(const T& x) //O(lgN)
    {
        _h.Push(x);
    }
    void Pop()
    {
        _h.Pop();
    }
protected:
    Heap<T> _h;
};

2. N个数中找出最大的前K个数(N>M)

//思路:先读取K个建小堆,每次读取一个与堆顶比较,若大则让堆顶
//与这个数交换,然后做一次向下调整。
#pragma once
#include<iostream>
#include<time.h>
#include<assert.h>
using namespace std;
const int N = 10000;
const int K = 100;

void AdjustDown(int topk[],int size,int parent) //建小堆
{
    int child = 2 * parent + 1;
    while (child < size)
    {
        if ((child + 1 < size) && (topk[child] > topk[child + 1]))
        {
            child++;
        }
        if (topk[parent] > topk[child])
        {
            swap(topk[child], topk[parent]);
            parent = child;
            child = 2 * parent + 1;
        }
        else
        {
            break;
        }
    }
}
void GetK(int a[])
{
    assert(K < N);
    int topk[K];
    for (int i = 0; i < K; ++i)
    {
        topk[i] = a[i];
    }
    //建堆
    for (int i = (K - 2) / 2; i >= 0; --i)
    {
        AdjustDown(topk,K,i);
    }

    for (int i = K; i < N; ++i)
    {
        if (a[i]>topk[0])
        {
            topk[0] = a[i];
            AdjustDown(topk, K, 0);
        }
    }
    for (int i = 0; i < K; ++i)
    {
        cout << topk[i] << " ";
    }
}

void Test2()
{
    srand(time(0));
    int a[N] = { 0 };
    for (int i = 0; i < N; ++i)
    {
         a[i] = rand();
    }
    GetK(a);

}

3. 堆排序。

//思路:j建一个大堆,把堆顶元素交换到末尾,
//剩下数据向下调整
#pragma once
#include<iostream>
#include<assert.h>
using namespace std;

void AdjustDown(int a[], int size, int parent)
{
    int child = 2 * parent + 1;
    while (child < size)
    {
        if ((child + 1 < size) && (a[child] < a[child + 1]))
        {
            child++;
        }
        if (a[parent] < a[child])
        {
            swap(a[child], a[parent]);
            parent = child;
            child = 2 * parent + 1;
        }
        else
        {
            break;
        }
    }
}
void HeapSort(int a[],int size)
{
    assert(a);
    //建大堆
    for (int i = (size - 2) / 2; i >= 0; --i)
    {
        AdjustDown(a,size,i);
    }
    for (int i = 0; i < size; i++)
    {
        swap(a[0], a[size - 1 - i]);
        AdjustDown(a, size - 1 - i, 0);
    }
    
}

void Test3()
{
    int a[] = { 2, 6, 3, 8, 49, 95, 1, 5, 8 };
    int size = sizeof(a) / sizeof(a[0]);
    HeapSort(a, size);
    for (int i = 0; i < size; i++)
    {
        cout << a[i] << " ";
    }

结果如下:

wKioL1cy1LiyrIX2AAAr_D8m0eI491.png

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章