# 算法导论第六章优先队列（二）

1）Insert(S, x):插入x到集合S中；

2）Maximum(S):返回S中具有最大关键字的元素；

3）Extract_Max(S):去掉并返回集合S中具有最大关键字的元素；

4）Increase_Key(S, x, key):将元素x的关键字增加到key。

1 int PriorityQueue::HeapMaximum()    //return the maximum key from priority queue;
2 {
3     return GetQueueElement(0);        //the first element is max;
4 }

 1 int PriorityQueue::HeapExtractMax()        //delete and return the maximum key from queue;
2 {
3     if (IsEmptyHeap())
4         throw "heap underflow";
5
6     int heap_size = GetHeapSize();
7     int maxNum = GetQueueElement(0);
8     SetQueueElement(0, GetQueueElement(heap_size-1)); //A[1] = A[heap_size]
9     SetHeapSizeMinus1();
10     MaxHeapify(0);    //Max_Heapify()
11     return maxNum;
12 }

 1 void PriorityQueue::HeapIncreaseKey(int srcIndex, int dstKey)    //increasing the srcKey to dstKey
2 {
3     if (dstKey < GetQueueElement(srcIndex))
4         throw "new key is smaller than current key!";
5     SetQueueElement(srcIndex, dstKey); //x = key
6     while(srcIndex > 0 && GetQueueElement(getParent(srcIndex)) < GetQueueElement(srcIndex)) {
7         Swap(srcIndex, getParent(srcIndex));
8         srcIndex = getParent(srcIndex); //get parent
9     }
10 }

1 void PriorityQueue::HeapInsert(int key)    //insert key to the priority queue;
2 {
4     int heap_size = GetHeapSize();
5     HeapIncreaseKey(heap_size-1, key);
6 }

1 Heap-Delete(A, i)
2     A[i] = A[A.heap-size]
3     A.heap-size = A.heap-size - 1
4     Heapify(A, i)

.h 文件

 1 #ifndef _PRIORITY_QUEUE_H_
2 #define _PRIORITY_QUEUE_H_
3
4 /************************************************************************/
5 /*    priority queue
6 /************************************************************************/
7 class PriorityQueue {
8 public:
9     PriorityQueue() { m_heapSize = 0; m_length = 0; }
10     ~PriorityQueue() {}
11
12     //inline
13     int getParent(int index) { return (index-1)/2; }
14     int getLeft(int index) { return 2*index + 1; }
15     int getRight(int index) { return 2*index + 2; }
16
17     //heap operation
18     void BuildMaxHeap();        //build the max heap
19     void MaxHeapify(int index);    //protect the max heap
20     void HeapSort();            //heap sort
21
22     //priority queue operation
23     void HeapInsert(int key);    //insert key to the priority queue;
24     int HeapMaximum();            //return the maximum key from priority queue;
25     int HeapExtractMax();        //delete and return the maximum key from queue;
26     void HeapIncreaseKey(int srcIndex, int dstKey);    //increasing the srcKey to dstKey
27
28     void HeapDelete(int key);    //delete key Ï°Ìâ6.5-8
29
30     //other assist functions
32     void DisplayQueue();
33     void DisplayHeapQueue();
34
35 public:
36
37
38 private:
39     int GetQueueElement(int index) { return m_vecQueue[index]; }
40     void SetQueueElement(int index, int key) { m_vecQueue[index] = key; }
41     void Swap(int i, int j) {
42         int temp = m_vecQueue[i];
43         m_vecQueue[i] = m_vecQueue[j];
44         m_vecQueue[j] = temp;
45     }
46     int GetHeapSize() { return m_heapSize; }
47     int GetArrayLength() { return m_length; }
48     void SetHeapSizeMinus1() { m_heapSize = m_heapSize - 1; }
49     void SetHeapSizePlus1() { m_heapSize = m_heapSize + 1; }
50
51     bool IsEmptyHeap() { return (m_heapSize > 1 ? false : true); }
52
53 private:
54     vector<int>        m_vecQueue;
55     int                m_heapSize;    //¶ÑÔªËØ¸öÊý
56     int                m_length;    //Êý×éÔªËØ¸öÊý
57
58 };
59
60
61 #endif//_PRIORITY_QUEUE_H_

.cpp 文件

  1 #include <iostream>
2 #include <vector>
3 using namespace std;
4
5 #include "PriorityQueue.h"
6
7 //heap operation
8 void PriorityQueue::BuildMaxHeap()        //build the max heap
9 {
10     int heap_size = GetHeapSize();
11     for (int i = (heap_size-1)/2; i >= 0; i --)
12         MaxHeapify(i);
13 }
14
15 void PriorityQueue::MaxHeapify(int index)    //protect the max heap
16 {
17     if (index < 0 || index >= GetHeapSize())
18         return;
19
20     int heap_size = GetHeapSize();
21     bool isHeapify = true;
22
23     int largest = -1;
24     while (isHeapify && index < heap_size) {
25         int left = getLeft(index);
26         int right = getRight(index);
27
28         if (left < heap_size && GetQueueElement(left) > GetQueueElement(index) )
29             largest = left;
30         else
31             largest = index;
32         if (right < heap_size && GetQueueElement(right) > GetQueueElement(largest) )
33             largest = right;
34
35         if (largest != index) {
36             Swap(index, largest);
37             index = largest;
38         }
39         else
40             isHeapify = false;
41     }
42
43 }
44
45 void PriorityQueue::HeapSort()            //heap sort
46 {
47     BuildMaxHeap();
48     int heap_size = GetHeapSize();
49     for (int i = heap_size-1; i >= 1; i --) {
50         Swap(0, i);
51         SetHeapSizeMinus1(); //heap_size--;
52         MaxHeapify(0);
53     }
54 }
55
56 //priority queue operation
57 void PriorityQueue::HeapInsert(int key)    //insert key to the priority queue;
58 {
59 //     SetHeapSizePlus1();
60 //     int heap_size = GetHeapSize();
62     int heap_size = GetHeapSize();
63     HeapIncreaseKey(heap_size-1, key);
64 }
65
66 int PriorityQueue::HeapMaximum()    //return the maximum key from priority queue;
67 {
68     return GetQueueElement(0);        //the first element is max;
69 }
70
71 int PriorityQueue::HeapExtractMax()        //delete and return the maximum key from queue;
72 {
73     if (IsEmptyHeap())
74         throw "heap underflow";
75
76     int heap_size = GetHeapSize();
77     int maxNum = GetQueueElement(0);
78     SetQueueElement(0, GetQueueElement(heap_size-1)); //A[1] = A[heap_size]
79     SetHeapSizeMinus1();
80     MaxHeapify(0);    //Max_Heapify()
81     return maxNum;
82 }
83
84 void PriorityQueue::HeapIncreaseKey(int srcIndex, int dstKey)    //increasing the srcKey to dstKey
85 {
86     if (dstKey < GetQueueElement(srcIndex))
87         throw "new key is smaller than current key!";
88     SetQueueElement(srcIndex, dstKey); //x = key
89     while(srcIndex > 0 && GetQueueElement(getParent(srcIndex)) < GetQueueElement(srcIndex)) {
90         Swap(srcIndex, getParent(srcIndex));
91         srcIndex = getParent(srcIndex); //get parent
92     }
93 }
94
95 void PriorityQueue::HeapDelete(int key)    //delete key Ï°Ìâ6.5-8
96 {
97     int heap_size = GetHeapSize();
98     int index = 0;
99     for (;index < heap_size; index ++) {
100         if (GetQueueElement(index) == key)
101             break;
102     }
103     SetQueueElement(index, GetQueueElement(heap_size-1));
104     SetHeapSizeMinus1();
105     MaxHeapify(index);
106 }
107
108 //other assist functions
109 void PriorityQueue::DisplayQueue()
110 {
111     int nLen = GetArrayLength();
112     cout << "------------------------" << endl;
113     for (int i = 0; i < nLen; i ++)
114         cout << GetQueueElement(i) << " ";
115     cout << endl;
116 }
117
118 void PriorityQueue::DisplayHeapQueue()
119 {
120     int heap_size = GetHeapSize();
121     cout << "------------------------" << endl;
122     for (int i = 0; i < heap_size; i ++)
123         cout << GetQueueElement(i) << " ";
124     cout << endl;
125 }
126
128 {
129     m_vecQueue.push_back(key);
130     m_heapSize ++;
131     m_length ++;
132 }
133
134
135 // int main()
136 // {
137 //     //int key, num;
138 //     PriorityQueue PQ;
139 //
140 // //     cout << "the number:" << endl;
141 // //     cin >> num;
142 //     int arr[] = {10,8,7,16,14,9,3,2,4,1};
143 //     cout << "the key:" << endl;
144 //     for (int i = 0; i < 10; i ++) {
146 //     }
147 //
148 //     PQ.BuildMaxHeap();
149 //     PQ.DisplayQueue();
150 //
151 //     //Max
152 //     cout << "Max:" << PQ.HeapMaximum() << endl;
153 //
154 //     //IncreaseKey
155 //     cout << "IncreaseKey:" << endl;
156 //     PQ.HeapIncreaseKey(0, 18);
157 //     PQ.DisplayHeapQueue();
158 //
159 //     //InsertKey
160 //     cout << "InsertKey:" << endl;
161 //     PQ.HeapInsert(20);
162 //     PQ.DisplayHeapQueue();
163 //
164 //     //Extract_Max
165 //     cout << "Extract_Max:" << PQ.HeapExtractMax() << endl;
166 //     PQ.DisplayHeapQueue();
167 //
168 //     //Extract_Max
169 //     cout << "Extract_Max:" << PQ.HeapExtractMax() << endl;
170 //     PQ.DisplayHeapQueue();
171 //
172 //     return 0;
173 // }

1）习题6.5-6：在Heap_Increase_Key的第5行操作中，一般需要通过三次赋值来完成。想一想如何利用Insertion_Sort内循环部分的思想，只用一次赋值就完成这一交换操作？

1 Heap-Increase-Key(A, i, key)
2     if A[i] < key
3         error "new key is smaller than original"
4     while i > 1 and A[Parent(i)] < key
5         A[i] = A[Parent(i)]
6         i = Parent(i)
7     A[i] = key

2）习题6.5-9：请设计一个能够在O(nlgk)的算法，它能够将k个有序链表合并成一个有序链表，这里n是所有输入链表包含的总的元素个数。（提示：使用最小堆来完成k路归并）。

  1 #include <iostream>
2 #include <vector>
3
4 using namespace std;
5
6
7 #include "MinHeap.h"
8
9 //merge the k list to a heap;
10 template<class T>
11 MinHeap<T>::MinHeap(size_t kSize)
12 {
13     if (!m_minHeap)
14         delete []m_minHeap;
15     m_minHeap = new T[kSize+1];
16     m_heapSize = 0;
17 }
18
20 template<class T>
21 void MinHeap<T>::MinHeapify(const size_t index)
22 {
23     //assert
24     int heap_size = GetHeapSize();
25
26     while (true) {
27         size_t left = LEFT(index);
28         size_t right = RIGHT(index);
29
30         size_t smallest;
31         if (left < heap_size && HeapCompare(index, left) > 0)
32             smallest = left;
33         else smallest = index;
34         if (right < heap_size && HeapCompare(smallest, right) > 0)
35             smallest = right;
36
37         if (smallest != index) {
38             Swap(index, smallest);
39             index = smallest;
40         }
41         else break;
42     }
43 }
44
45 //insert element
46 template<class T>
47 void MinHeap<T>::HeapInsert(const T &element)
48 {
49     m_minHeap[m_heapSize] = element;
50     m_heapSize += 1;
51
52     size_t index = m_heapSize-1;
53
54     while (index > 0 && HeapCompare(index, PARENT(index)) < 0) {
55         Swap(index, PARENT(index));
56         index = PARENT(index);
57     }
58 }
59
60 //return and delete the min element
61 template<class T>
62 T MinHeap<T>::HeapExtractMin() const
63 {
64     if (IsEmptyHeap())
65         throw "Heap is Empty!";
66     T minElement = HeapMin();
67
68     int heap_size = GetHeapSize();
69     m_minHeap[0] = m_minHeap[heap_size-1];
70     m_heapSize -= 1;
71     MinHeapify(0);
72     return minElement;
73 }
74
75 //return min element;
76 template<class T>
77 T    MinHeap<T>::HeapMin() const
78 {
79     return m_minHeap[0];
80 }
81
82 int main()
83 {
84     size_t k = 3;
85     vector<int> vecList[k];
86     vector<int>::iterator iterList[k];
87     vector<int> vecSort;
88     vector<int>::iterator iterS;
89
90     vector<int>::iterator it;
91
92     MinHeap<vector<int>::iterator> minHeap(k);
93     //first list
94     vecList[0].push_back(12);
95     vecList[0].push_back(24);
96     vecList[0].push_back(52);
97     cout << "first list:" << endl;
98     for ( it = vecList[0].begin();it != vecList[0].end(); ++it)
99         cout << *it << "->";
100     cout << "NULL" << endl;
101
102     vecList[1].push_back(9);
103     vecList[1].push_back(32);
104
105     cout << "second list:" << endl;
106     for ( it = vecList[1].begin();it != vecList[1].end(); ++it)
107         cout << *it << "->";
108     cout << "NULL" << endl;
109
110     vecList[2].push_back(34);
111     vecList[2].push_back(42);
112     vecList[2].push_back(78);
113     cout << "third list:" << endl;
114     for ( it = vecList[2].begin();it != vecList[2].end(); ++it)
115         cout << *it << "->";
116     cout << "NULL" << endl;
117
118     iterList[0] = vecList[0].begin();
119     iterList[1] = vecList[1].begin();
120     iterList[2] = vecList[2].begin();
121
122     minHeap.HeapInsert(iterList[0]);
123     minHeap.HeapInsert(iterList[1]);
124     minHeap.HeapInsert(iterList[2]);
125
126     while(minHeap.GetHeapSize()) {
127         it = minHeap.HeapExtractMin();
128         vecSort.push_back(*it);
129         ++it;
130         if (it != vecList[0].end()&& it != vecList[1].end() && it != vecList[2].end()) {
131             minHeap.HeapInsert(it);
132         }
133     }
134
135     cout << "meger:" << endl;
136     for (iterS = vecSort.begin(); iterS != vecSort.end(); ++ iterS)
137         cout << *iterS << "->";
138     cout << "NULL" << endl;
139
140     return 0;
141 }

posted @ 2015-09-20 17:16  bakari  阅读(1047)  评论(0编辑  收藏  举报