异常类 myExceptions 同 数据结构C++(1)线性表——数组实现(arrayList) 。
抽象基类 maxPriorityQueue 定义在 maxPriorityQueue.h 中:
1 #pragma once
2
3 template<class T>
4 class maxPriorityQueue
5 {
6 public:
7 virtual ~maxPriorityQueue() {}
8 virtual bool empty() const = 0;
9 virtual int size() const = 0;
10 virtual const T& top() = 0;
11 virtual void pop() = 0;
12 virtual void push(const T& theElement) = 0;
13 };
类 maxHeap 在 maxHeap.h 中实现:
1 #pragma once
2 #include <iostream>
3 #include <vector>
4 #include <string>
5 #include "myExceptions.h"
6 #include "maxPriorityQueue.h"
7
8
9 template<typename T>
10 class maxHeap : public maxPriorityQueue<T>
11 {
12 public:
13 maxHeap(int initArrayLenth = 20);
14 ~maxHeap() { delete heap; }
15 bool empty() const { return heapSize == 0; }
16 int size() const { return heapSize; }
17 const T& top(); //返回根
18 void pop(); //删除
19 void push(const T& theElement); //插入
20
21 void initialize(T *dataArray, int arraySize); //大根堆初始化
22 protected:
23 int heapSize;
24 std::vector<T> *heap; // element array
25 };
26
27 template<typename T>
28 maxHeap<T>::maxHeap(int initArrayLenth)
29 {
30 if (1 > initArrayLenth)
31 throw illegalParameterValue();
32 heap = new std::vector<T>(initArrayLenth + 1);
33 heapSize = 0;
34 }
35
36 template<typename T>
37 const T& maxHeap<T>::top() //返回根
38 {
39 if (0 == heapSize)
40 throw queueEmpty();
41 return heap->at(1);
42 }
43
44 template<typename T>
45 void maxHeap<T>::pop() //删除
46 {
47 if (heapSize == 0)
48 throw queueEmpty();
49
50 // 最后一个元素
51 T lastElement = heap->at(heapSize);
52 heap->erase(heap->begin() + heapSize);
53 heapSize--;
54 // 寻找新的插入位置
55 int currentNode = 1,
56 child = 2; // currentNode 的左子树
57 while (child <= heapSize)
58 {
59 // 取左右子树中的大者
60 if (child < heapSize && heap->at(child) < heap->at(child + 1))
61 child++;
62
63 // 若 最后一个元素不小于 currentNode 的子树
64 if (lastElement >= heap->at(child))
65 break; // 则将其插入
66 heap->at(currentNode) = heap->at(child); // 较大的子树成为 父节点
67 currentNode = child; // currentNode,child 向下移动一层
68 child *= 2;
69 }
70 heap->at(currentNode) = lastElement;
71 }
72
73 template<typename T>
74 void maxHeap<T>::push(const T& theElement) //插入
75 {
76 // 为元素 theElement 寻找插入位置
77 int NewNode = ++heapSize;
78 while (NewNode != 1 && heap->at(NewNode / 2) < theElement)
79 {
80 // theElement 不能够插入到 heap[NewNode], 将 theElement 与 父节点交换
81 if (NewNode >= heap->size())
82 heap->insert(heap->begin() + NewNode, heap->at(NewNode / 2));
83 else
84 heap->at(NewNode) = heap->at(NewNode / 2);
85 NewNode /= 2;
86 }
87 if (!(NewNode >= heap->size()))
88 heap->at(NewNode) = theElement;
89 else
90 heap->insert(heap->begin() + NewNode, theElement);
91 }
92
93 template<typename T>
94 void maxHeap<T>::initialize(T *dataArray, int arraySize) //大根堆初始化
95 {
96 if ((nullptr == dataArray) || (1 > arraySize))
97 throw illegalInputData();
98
99 delete heap;
100 heap = new std::vector<T>(arraySize);
101 for (int i = 0; i < arraySize; i++)
102 heap->insert(heap->begin() + i, dataArray[i]);
103 heapSize = arraySize;
104
105 //heap[1 ---> root] 都可能有子树
106 for (int root = heapSize / 2; root >= 1; root--)
107 {
108 T rootElement = heap->at(root);
109
110 // 寻找元素 rootElement 的插入位置
111 int child = 2 * root;
112 while (child <= heapSize)
113 {
114 // heap[child] 是两个子树中较大的
115 if ((child < heapSize) && (heap->at(child) < heap->at(child + 1)))
116 child++;
117
118 // rootElement 作为根,不小于 heap[child] ,则插入
119 if (rootElement >= heap->at(child))
120 break;
121 heap->at(child / 2) = heap->at(child); // 否则,heap[child] 作为根
122 child *= 2; // 移动到下一层,若不符合 while 条件,则将 rootElement 插入
123 }
124 heap->at(child / 2) = rootElement;
125 }
126 }
参考文献:
[1].Sartaj Sahni. 数据结构、算法与应用[M]. 机械工业出版社, 2000.