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

    xiaoxiao2026-06-22  1

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

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

    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; }
    转载请注明原文地址: https://ju.6miu.com/read-1310773.html
    最新回复(0)