堆的應用

  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

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