数据结构C++(11)大根堆——vector实现(maxHeap)

异常类 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.

转载于:https://www.cnblogs.com/peformer/p/8067511.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值