- 堆的概念
堆数据结构是一种数组对象,它可以被视为一棵完全二叉树结构。
堆结构的二叉树存储是最大堆:每个父节点的都大于孩子节点。
最小堆:每个父节点的都小于孩子节点。
- 堆的结构
1 #include <vector> 2 template<class T> 3 class Heap 4 { 5 public: 6 Heap(); 7 Heap(const T* array, size_t size) 8 { 9 for (size_t i = 0; i < size; i++) 10 { 11 _array.push_back(array[i]); 12 } 13 //建堆 14 for (int i = (_array.size() - 2)/2; i >= 0; i--) 15 { 16 _AdjustDown(i); 17 } 18 } 19 //插入一个数据x到堆中 20 void Push(const T& x) 21 { 22 _array.push_back(x); 23 _AdjustUp(_array.size() - 1); 24 } 25 //删除堆顶元素 26 void Pop() 27 { 28 assert(_array.size() > 0); 29 swap(_array[0], _array[_array.size() - 1]); 30 _array.pop_back(); 31 _AdjustDown(0); 32 } 33 T& GetTop() 34 { 35 assert(_array.size() > 0); 36 return _array[0]; 37 } 38 //将根节点向下调整 39 void _AdjustDown(int root) 40 { 41 int child = root * 2 + 1; 42 while (child < _array.size()) 43 { 44 //比较出左右孩子中大的那个 45 if (child + 1 < _array.size() && _array[child + 1] > _array[child]) 46 { 47 child++; 48 } 49 //与根节点相比 50 if (_array[child]>_array[root]) 51 { 52 swap(_array[child], _array[root]); 53 root = child; 54 child = root * 2 + 1; 55 } 56 else 57 { 58 break; 59 } 60 } 61 } 62 //一个节点向上调整 63 void _AdjustUp(int child) 64 { 65 int parent = (child - 1) / 2; 66 while (child > 0) 67 { 68 if (_array[child] > _array[parent]) 69 { 70 swap(_array[child], _array[parent]); 71 child = parent; 72 parent = (child - 1) / 2; 73 } 74 else 75 { 76 break; 77 } 78 } 79 } 80 void Print() 81 { 82 for (size_t i = 0; i < _array.size(); ++i) 83 { 84 cout << _array[i] << " "; 85 } 86 cout << endl; 87 } 88 //判断是否为空 89 bool Empty() 90 { 91 return _array.empty(); 92 } 93 size_t Size() 94 { 95 return _array.size(); 96 } 97 98 public: 99 vector<T> _array; 100 };
- 堆的应用:
100w个数中找出最大的前K个数
1 //100w个数中找出最大的前k个数 2 #define M 1000000 3 #define N 100 4 void _Adjustdown(int *Ma, int k, int root) 5 { 6 int child = root * 2 + 1; 7 while (child < k) 8 { 9 if ((child + 1 )< k&&Ma[child + 1] < Ma[child]) 10 { 11 child++; 12 } 13 if (Ma[child] < Ma[root]) 14 { 15 swap(Ma[child], Ma[root]); 16 root = child; 17 child = root * 2 + 1; 18 } 19 else 20 { 21 break; 22 } 23 } 24 25 } 26 int* FindMaxKNum(int* array,int *Ma,int size,int k) 27 { 28 for (int i = 0; i < k; i++) 29 { 30 Ma[i] = array[i]; 31 } 32 33 for (int i = (k - 2) / 2; i >= 0; --i) 34 { 35 _Adjustdown(Ma, k, i); 36 } 37 for (int i = k; i < size; ++i) 38 { 39 if (array[i] > Ma[0]) 40 { 41 Ma[0] = array[i]; 42 _Adjustdown(Ma, k, 0); 43 } 44 } 45 return Ma; 46 } 47 void TestFindPreKNum() 48 { 49 int *array = new int[M]; 50 int *Ma = new int[N]; 51 for (int i = 0; i < M; i++) 52 { 53 array[i] = i; 54 } 55 56 int* ret = FindMaxKNum(array, Ma, M,N); 57 for (int i = 0; i < N; ++i) 58 { 59 cout << *(ret + i) << " "; 60 } 61 cout << endl; 62 delete []array; 63 delete []Ma; 64 65 }