堆:實質是一顆完全二叉樹,最大堆的特點:父節點值均大於子節點;最小堆的父節點值均小於子節點;
一般使用連續內存存儲堆內的值,因而可以根據當前節點的索引值推斷子節點的索引值:
節點i的父節點為(i-1)/2;
節點j的左子結點:j * 2 + 1;
節點j的右子結點:j * 2 + 2;
以下代碼實現了最大堆最小堆,當比較函數使用std::greater,得到最大堆,當比較函數使用std::less得到最小堆;
代碼及測試用例如下:
1 //最大最小堆 2 //MaxMinHeap.h 3 4 #pragma once 5 #include <assert.h> 6 7 using namespace std; 8 9 template <typename T> 10 void mswap(T &a, T &b) 11 { 12 T tmp = a; 13 a = b; 14 b = tmp; 15 } 16 17 template <typename T,typename Compare = std::less<T>> 18 class MaxMinHeap 19 { 20 public: 21 int hSize ; //堆空間 22 int hCurNum;//堆內已占用空間 23 T *data; 24 25 private: 26 Compare comp;//比較函數 27 public: 28 MaxMinHeap(int size) 29 { 30 hSize = size; 31 assert(hSize>0); 32 data = new T[hSize]; 33 hCurNum = 0; 34 }; 35 ~MaxMinHeap(void) 36 { 37 if(data!=NULL) 38 delete []data; 39 }; 40 41 void headAdd(T num) 42 { 43 if (hCurNum==hSize) 44 { 45 if (comp(num,data[0]))//greater 大頂堆 保留最小的K個數;less 小頂堆 保留最大的K個數 46 return; 47 data[0]=num; 48 HeapFixDown(0,hCurNum); 49 } 50 else 51 { 52 data[hCurNum++]=num; 53 HeapFixUp(hCurNum-1); 54 } 55 }; 56 //最大堆排序后得到升序序列;最小堆排序后得到降序序列 57 void sort() 58 { 59 for (int i=hCurNum-1; i >=1 ; --i) 60 { 61 mswap(data[i],data[0]); 62 HeapFixDown(0,i); 63 } 64 } 65 66 void GetHnum(T &n)//獲取最大堆的最小值或者最小堆的最大值 67 { 68 n = data[0]; 69 }; 70 void HeapFixUp(int index) 71 { 72 assert (index < hCurNum); 73 T tmp=data[index]; 74 int j = (index - 1)/2;//父節點 75 while(j>=0 && index !=0) 76 { 77 if(comp(data[j],tmp)) 78 break; 79 data[index]=data[j]; 80 index = j; 81 j = (index - 1)/2; 82 } 83 data[index]=tmp; 84 }; 85 86 //從節點index開始進行向下調整 87 void HeapFixDown(int index, int n) 88 { 89 assert(index<hCurNum); 90 assert(n<hCurNum); 91 92 T tmp=data[index]; 93 int j = index*2+1; 94 while(j<n) 95 { 96 if(j+1 < n && comp(data[j+1],data[j]))//大頂堆中左右孩子找最大的,小頂堆左右孩子找最小的 97 ++j; 98 if(comp(tmp,data[j])) 99 break; 100 data[index]=data[j]; 101 index = j; 102 j = index*2+1; 103 } 104 data[index]=tmp; 105 }; 106 }; 107 108 #include <functional> 109 #include <iostream> 110 #include "MaxMinHeap.h " 111 112 using namespace std; 113 114 int main(int argc , char ** argv) 115 { 116 MaxMinHeap<float,greater<float>> test(20); 117 118 for (int i = 0 ;i < 20; ++i) 119 { 120 test.headAdd(-i*2+38); 121 } 122 for (int i = 0 ; i < 20 ; ++i) 123 { 124 cout<<test.data[i]<<endl; 125 } 126 test.sort(); 127 for (int i = 0 ; i < 20 ; ++i) 128 { 129 cout<<test.data[i]<<" "; 130 } 131 cout<<endl; 132 return 0; 133 }