当你只需要找到最大最小值而不需要查找其他元素时,可以用二叉堆,不需要用用叉查找树。
2 #include<iostream>
3 using std::cin;
4 using std::cout;
5 using std::vector;
6 using std::endl;
7
8 template <typename Comparable>
9 class BinaryHeap{
10 public:
11 explicit BinaryHeap(int capacity=100);
12 explicit BinaryHeap(const vector<Comparable>& items)
13 :array(items.size()+10),currentSize(items.size()){
14 for(int i=0;i<items.size();i++)
15 array[i+1]=items[i];
16 buildHeap();
17 }
18
19 bool isEmpty() const;
20 const Comparable & findMin() const;
21
22 void insert(const Comparable & x);
23 void deleteMin();
24 void deleteMin(Comparable & minItem);
25 void makeEmpty();
26
27
28 int currentSize;
29 vector<Comparable> array;
30 private:
31 void buildHeap();
32 void percolateDown(int hole);
33 };
34
35 template <typename Comparable>
36 bool BinaryHeap<Comparable>::isEmpty() const{
37 return currentSize==0;
38 }
39
40 template <typename Comparable>
41 void BinaryHeap<Comparable>::insert(const Comparable & x){
42 if(currentSize==array.size()-1)
43 array.resize(array.size()*2);
44 int hole=++currentSize;
45 for(;hole>1&&x<array[hole/2];hole/=2)
46 array[hole]=array[hole/2];
47 array[hole]=x;
48 }
49
50 template <typename Comparable>
51 void BinaryHeap<Comparable>::deleteMin(){
52 if(isEmpty())
53 throw;// UnderflowException();
54 array[1]=array[currentSize--];
55 percolateDown(1);
56 }
57
58 template <typename Comparable>
59 void BinaryHeap<Comparable>::deleteMin(Comparable & minItem){
60 if(isEmpty())
61 throw;// UnderflowException();
62 minItem=array[1];
63 array[1]=array[currentSize--];
64 percolateDown(1);
65 }
66
67 template <typename Comparable>
68 void BinaryHeap<Comparable>::percolateDown(int hole){
69 int child;
70 Comparable tmp=array[hole];
71 for(;hole*2<=currentSize;hole=child){
72 child=hole*2;
73 if(child!=currentSize&&array[child+1]<array[child])
74 child++;
75 if(array[child]<tmp)
76 array[hole]=array[child];
77 else
78 break;
79 }
80 array[hole]=tmp;
81 }
82
83 template <typename Comparable>
84 void BinaryHeap<Comparable>::buildHeap(){
85 for(int i=currentSize/2;i>0;i--)
86 percolateDown(i);
87 }
88
89 int main(){
90 vector<int> array;
91 for(int num=150;num>10;num-=10)
92 array.push_back(num);
93 BinaryHeap<int> heap(array);
94 for(int i=1;i<=heap.currentSize;i++)
95 cout<<heap.array[i]<<"";
96 cout<<endl;
97
98 int min=0;
99 heap.deleteMin(min);
100 cout<<"The minimun value of heap:"<<min<<endl;
101
102 for(int i=1;i<=heap.currentSize;i++)
103 cout<<heap.array[i]<<"";
104 cout<<endl;
105
106 return0;
107 }
108
D:\C++>g++ BinaryHeap.cpp -o BinaryHeap
D:\C++>BinaryHeap.exe
20 50 30 70 60 40 90 80 120 140 110 150 100 130
The minimun value of heap:20
30 50 40 70 60 100 90 80 120 140 110 150 130
STL中的priority_queue
函数配接器Function Adapter
能够将仿函数和另一个仿函数结合起来的仿函数。函数配接器声明于<functional>中。
Priority Queue定义于文件<queue>中,其声明如下:
template<typename _Tp,
typename _Sequence = vector<_Tp>,
typename _Compare = less<typename _Sequence::value_type> >
class priority_queue
3 #include<queue>
4 #include<functional>
5 #include<string>
6
7 usingnamespace std;
8
9 template <typename PriorityQueue>
10 void dumpContents(conststring& msg,PriorityQueue & pq){
11 cout<<msg<<":"<<endl;
12 while(!pq.empty()){
13 cout<<pq.top()<<endl;
14 pq.pop();
15 }
16 }
17
18 int main(){
19 priority_queue<int> maxPQ;
20 priority_queue<int,vector<int>,greater<int>> minPQ; //默认情况下用的是less<int>
21
22 minPQ.push(150);minPQ.push(140);minPQ.push(130);minPQ.push(120);minPQ.push(110);minPQ.push(100);minPQ.push(90);
23 maxPQ.push(150);maxPQ.push(140);maxPQ.push(130);maxPQ.push(120);maxPQ.push(110);maxPQ.push(100);maxPQ.push(90);
24
25 dumpContents("minPQ",minPQ);
26 dumpContents("maxPQ",maxPQ);
27
28 return0;
29 }
D:\C++>priority_queue.exe
minPQ:
90
100
110
120
130
140
150
maxPQ:
150
140
130
120
110
100
90
自定义比较方法:
有两种策略可供选择:
(1)自定义比较器
class CMP{ public: bool operator() (const Comparable & a,const Comparable &b)const{ return a.value<b.value; } };
只需要重载operator()就可以了。
(2)在自已的类中重载operator<,因为在priority_queue中使用的默认比较器就是less<object>
class Comparable{ public: int value; bool operator< (const Comparable &b) const{ return value<b.value; } };