二叉堆
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

浙公网安备 33010602011771号