• 二叉堆


    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;
    }
    
  • 相关阅读:
    Arm的几种工作模式
    Linux 串口驱动初始化前置定位crash log
    GPS的经纬度格式及转换
    git 常用命令
    windows 下 mongodb studio 3t 破解无限使用脚本
    从头开始 一、第一天
    十九、IDEA的pom文件手动添加依赖
    十八、{ "a", "ab", "ac", "abc", "de", "bc", "e" }不使用Arrays.sort()进行排序
    十七、Java中数组常见的几种排序方法!
    十六、IDEA创建一个maven工程
  • 原文地址:https://www.cnblogs.com/EvilGhost/p/BinaryHeap.html
Copyright © 2020-2023  润新知