C++模板类实现“堆”的经典案例学习+(优先队列)

来源:互联网 发布:辐射4妹子捏脸数据 编辑:程序博客网 时间:2024/05/16 15:15


             本文转自:《C++程序设计》   Y. Daniel  Liang著  王刚,刘晓光,刘璟 译, 机械工业出版社

             简单介绍堆的概念:堆,实际上就是一颗完全二叉树,它的每个节点的值都大于等于其任何孩子节点的值。


             堆是二叉树,因此可用二叉树的结构描述,但是,如果堆的大小预先可知的话,更为有效的描述方法是使用向量或数组。下面的代码使用的向量来描述的,操作比较简单。


             堆的删除操作步骤:

             1、将最后一个节点移至根节点,代替根;

             2、令根为当前结点;

             3、while(当前节点有孩子节点,且当前节点小于其中的某个孩子节点){

                              将当前节点与最大的孩子节点交换;

                              令当前节点为与与之交换的孩子节点;

                  }


            堆的插入操作步骤:

           1、将待插入节点,插入到堆的末尾; 

           2、令最后一个节点(新节点)为当前节点;

           3、while(当前节点大于其父节点){

                             将当前节点与其父节点交换;

                             当前节点变为为父节点;

                }


             代码实现:

            

#include<iostream>#include<string>#include<vector>#include<stdexcept>using namespace std;template<typename T=int>class Heap{public:    Heap(){};    Heap(T elements[], int arraySize){        for(int i=0; i<arraySize; i++){            add(elements[i]);        }    }    T remove() throw (runtime_error){        if(v.size()==0){            throw runtime_error("Heap is empty");        }        T removedElement = v[0];        v[0] = v[v.size()-1];        v.pop_back();//remove root        int currentIndex = 0;        while(currentIndex < v.size()){            int leftChildIndex = currentIndex * 2 + 1;            int rightChildIndex = currentIndex * 2 + 2;            if(leftChildIndex >= v.size()){                break;            }            int maxIndex = leftChildIndex;            if(rightChildIndex < v.size()){                if(v[maxIndex] < v[rightChildIndex]){                    maxIndex = rightChildIndex;                }            }            if(v[currentIndex] < v[maxIndex]){                T temp = v[maxIndex];                v[maxIndex] = v[currentIndex];                v[currentIndex] = temp;                currentIndex = maxIndex;            }            else{                break;            }        }        return removedElement;    }    void add(T element){        v.push_back(element);        int currentIndex = v.size() - 1;        while(currentIndex > 0){            int parentIndex = (currentIndex-1) / 2;            if(v[currentIndex] > v[parentIndex]){                T temp = v[currentIndex];                v[currentIndex] = v[parentIndex];                v[parentIndex] = temp;                currentIndex = parentIndex;            }            else{                break;            }        }    }    int getSize(){        return v.size();    }private:    vector<T> v;};template<typename T=int>class PriorityQueue{public:    PriorityQueue(){}        void enqueue(T element){        heap.add(element);    }    T dequeue() throw(runtime_error){        return heap.remove();    }    int getSize(){        return heap.getSize();    }private:    Heap<T> heap;};class Patient{public:    Patient(string name, int priority){        this->name = name;        this->priority = priority;    }    bool operator<(Patient &secondPatient){        return (this->priority < secondPatient.priority);    }    bool operator>(Patient &secondPatient){        return (this->priority > secondPatient.priority);    }    string getName(){        return this->name;    }    int getPriority(){        return this->priority;    }private:    string name;    int priority;};int main(){        PriorityQueue<Patient> patientQueue;    patientQueue.enqueue(Patient("John", 2));    patientQueue.enqueue(Patient("Jim", 1));    patientQueue.enqueue(Patient("Tim", 5));    patientQueue.enqueue(Patient("Cindy", 7));    while(patientQueue.getSize() > 0){        Patient element = patientQueue.dequeue();        cout << element.getName() << " (priority: " <<            element.getPriority() << " )";    }    return 0;}