优先级队列的简单实现及STL举例应用

优先级队列是堆的一个很常见的应用,在一些算法(如最小生成树算法)中会用到。可以用最大堆( 最大优先级队列 )或最小堆( 最小优先级队列 )进行实现。

作为队列的一种,优先级队列首先要有出队、入队、取队首、判空等基本操作,所不同的是出队、入队会改变堆中元素的顺序。

0. 调整堆的顺序(最大堆)

template<class T>void heapify(T *array, const int length, int i) {                       

    if (i < length) {                                                                     

        int parent_idx = i;                                                               

        int parent_val = array[parent_idx];                                               

        int child =2 * i + 1;                                                            

        while (child < length) {                                                          

            if (child + 1 < length && array[child] < array[child+1])                      

                child ++;                                                                 

            if (parent_val < array[child]) {                                             

                array[parent_idx] = array[child];                                         

                parent_idx = child;                                                       

                child = 2 * p +1;                                                        

            } else                                                                        

                break;                                                                    

        }                                                                                 

        array[parent_idx] = parent_val;                                                   

        //此时子树已经迭代完成,孩子中没有更大的了,不会上移,parent_val也不会下移了      

    }                                                                                     

};                                                                                        

  


1.入队

入队前,队列已经是一个堆了,所以入队的时候,只需要将它与parent比较,使它和parent的关系满足堆的性质。

template<class T>

void PriorityQueue<T>::enQueue(T *ele) {

   if (heap_size + 1> max_size) { //堆已满,需重新分配

        T *old_heap = heap;

        heap = new T[max_size * 2]; 

        for (int i = 0; i < heap_size; i++)

            heap[i] = old_heap[i];

        delete old_heap;

        old_heap = NULL;

   }   

   heap[heap_size] = *ele;

   int curr_idx = heap_size;

   int par_idx = parent(heap_size);

   ++ heap_size;

   while (par_idx >= 0 && heap[curr_idx] > heap[par_idx]) {

        T tmp = heap[curr_idx];

        heap[par_idx] = tmp;

        curr_idx = par_idx;

        par_idx = parent(curr_idx);

   }    

}



2. 出队
出队操作和堆排序进行的操作几乎完全相同。堆排序每次迭代都是将第一个元素与最后一个元素 对调 ,然后将堆大小减一,最后调用heapify保持堆的性质。而出队操作是将最后一个元素 赋值 给第一个元素,堆大小减一,调用heapify保持堆的性质。

template<class T>

void PriorityQueue<T>::deQueue(T * ele) {

    heap[0] = heap[heap_size - 1]; 

    -- heap_size;

    heapify(heap, heap_size, 0); 

}


3. STL中的优先级队列适配器
#include <iostream>
#include <queue>
using namespace std;
template <class T>
class Element {
    public:
    Element(int p, T a) {priority = p; data = a;}
    inline friend bool operator < (const Element<T> &a,  const Element<T> &b) {
        return a.priority < b.priority? true: false;
    }
    void PrintData() {
        cout << data << "(pri: " << priority << ")";
    }
    private:
    int priority;
    T data;
};

int main()
{
   cout << "Hello World" << endl; 
   priority_queue<Element<int> > pque;
   pque.push(Element<int>(1, 20));
   pque.push(Element<int>(3, 30));
   pque.push(Element<int>(2, 40));
   pque.push(Element<int>(3, 50));
   pque.push(Element<int>(3, 10));
   
   int size = (int)pque.size();
   cout << "size: " << size << endl;
   for (int i = 0; i < size; i++) {
       pque.top().PrintData();
       pque.pop();
   }
   cout << endl << "size: " << pque.size() << endl;
   return 0;
}



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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值