二叉堆
BinaryHeap.h文件
#ifndef BINARY_HEAP_H #define BINARY_HEAP_H namespace ghost{ template<typename A> void MinHeapShiftUp(A& array, const size_t size, size_t n/*umber(not index)*/) { if (0 == size) { // array为空 return; } if (size < n || 2 > n) { // n超出有效区间,或者没有父节点 return; } auto temp = array[n-1]; size_t holeN = n; // 建立空洞 while (true) { /// 测试父节点 size_t pn = holeN / 2; // 父节点number if (0 == pn) { // pn超出有效区间 break; } if (array[pn-1] > temp) { // 父节点较大下移,将空洞移动到父节点位置 array[holeN-1] = array[pn-1]; holeN = pn; } else { // 已经找到位置 break; } } if (holeN != n) { // 空洞位置发生变化,将节点放入空洞 array[holeN-1] = temp; } } template<typename A> void MinHeapShiftDown(A& array, const size_t size, size_t n/*umber(not index)*/) { if (0 == size) { // array为空 return; } if (size <= n || 0 == n) { // n超出有效区间,或者没有任何子节点 return; } auto temp = array[n-1]; size_t holeN = n; // 建立空洞 while (true) { /// 从空洞位置开始 size_t parentN = holeN; auto* pMin = &temp; /// 测试左子节点 size_t ln = 2 * parentN; // 左子节点number if (size < ln) { // ln超出有效区间 break; } if (array[ln-1] < *pMin) { // 左子节点较小,将空洞移动到左子节点位置 holeN = ln; pMin = &array[ln-1]; } /// 测试右子节点 size_t rn = ln + 1; // 右子节点number if (size >= rn) { if (array[rn-1] < *pMin) { // 右子节点较小,将空洞移动到右子节点位置 holeN = rn; pMin = &array[rn-1]; } } if (holeN == parentN/*&temp == pMin*/) { // 已经找到位置 break; } else { // 较小节点上移 array[parentN-1] = /*array[holeN-1]*/*pMin; } } if (holeN != n) { // 空洞位置发生变化,将节点放入空洞 array[holeN-1] = temp; } } template<typename A> void InitMinHeap(A& array, const size_t size) { for (size_t n = size/2; n > 0; --n) { MinHeapShiftDown(array, size, n); } } } // namespace ghost #endif // BINARY_HEAP_H
main.cpp文件
#include "FileDescriptor.h" #include "ResizableBuffer.h" #include "BinaryHeap.h" #include <iostream> #include <cassert> template<typename A> void PrintArray(A& array, const size_t size) { if (0 < size) { size_t endIndex = size - 1; for (size_t i = 0; i < endIndex; ++i) { std::cout<<array[i]<<","; } std::cout<<array[endIndex]; } std::cout<<std::endl; } int main() { std::cout<<"\n小根堆初始化:\n"<<std::endl; int array[] = {9,8,7,6,5,4,3,2,1,0}; size_t arraySize = sizeof(array)/sizeof(array[0]); PrintArray(array, arraySize); ghost::InitMinHeap(array, arraySize); std::cout<<"\n小根堆push模拟:\n"<<std::endl; for (int i = 0; (size_t)i < arraySize; ++i) { /// 因为测试用数组定长,所以我利用每次改变数组最后一个元素的值来模拟push操作(push操作就是先将元素插入到末尾,然后上滤) array[arraySize-1] = -(i); PrintArray(array, arraySize); ghost::MinHeapShiftUp(array, arraySize, arraySize); std::cout<<"->"; PrintArray(array, arraySize); } std::cout<<"\n小根堆pop模拟:\n"<<std::endl; for (int i = arraySize-1; i >= 0; --i) { /// 因为测试用数组定长,所以我利用每次将数组最后一个元素的值复制到数组头,然后将最后一个元素置0 ///(pop操作就是先将数组头元素临时保存,然后将最后一个元素提道数组头,最后从数组头开始下滤) PrintArray(array, arraySize); array[0] = array[i]; array[i] = 0; ghost::MinHeapShiftDown(array, i, 1); std::cout<<"->"; PrintArray(array, i); } std::cin.get(); ghost::FileDescriptor testFD(0); ghost::ResizableBuffer<int> testRB(1); std::cout << "Hello world!" << std::endl; return 0; }
By Evil.Ghost