zoukankan      html  css  js  c++  java
  • 数据结构

    数据结构 - 堆(Heap)

    1.堆的定义

    堆的形式满足完全二叉树的定义:

    • i < ceil(n/2) ,则节点i为分支节点,否则为叶子节点
    • 叶子节点只可能在最大的两层出现,而最大层次上的叶子节点都依次排列在该层最左侧的位置上
    • 如果有度为1的节点,那么只可能有一个,且该节点只有左孩子

    根据堆定义的不同,分为大根堆和小根堆:

    • 大根堆每个节点的值都大于其子节点的值
    • 小根堆每个节点的值都小于其子节点的值

    除此之外还有一个重要的内容:

    • 单节点也符合堆的特质

    2.堆的初始化

    堆的初始化可以可以分为如下几个步骤(以初始化最大根堆为例):

    1. 首先初始化为完全二叉树形式。
    2. 从最后一个具有孩子节点的节点进行调整,如果以该元素为根的子树是最大根堆,则不进行操作,否则将该子树调整为最大根堆(调整思路为不断与子节点进行比较和交换,直至满足最大根堆要求为止)。

    1. 数组:[2,7,26,25,19,17,90,3],初始化为完全二叉树形式。

    1. 调整最后一个具有孩子节点的节点[4],符合最大根堆要求,不进行操作。

    1. 调整节点[3],以满足最大根堆要求,交换[3][7]

    1. 调整节点[2],以满足最大根堆要求,交换[2][5]

    1. 调整节点[1],以满足最大根堆要求,交换[1][3]后继续交换[3][7],最终完成初始化,满足最大根堆要求。

    3.堆节点的插入和调整

    如上图所示,在如上所示图中插入44

    1. 与父节点比较[4] 小于 [9],进行交换。

    1. 与父节点比较[2] 小于 [4],进行交换。

    1. 与父节点比较[1] 大于 [2],调整结束。

    1. 堆的初始化和插入的C++语言代码描述
    /**
    *@Author : Kindear
    *@Intro  : DataStrcut C++ Code 以最大根堆为例
    **/
    #include <bits/stdc++.h>
    #define ARR_SIZE 20
    using namespace std;
    typedef int ElementType;
    void AdjustUp(ElementType A[],int k, int len) //该方法用于堆插入调整
    {
        int Tmp = A[k]; //暂存k位置的数值
        int i = k/2; //父节点的下标
        while(i > 0 && A[i] < Tmp)
        {
            //如果该节点大于父节点,那么就交换两者的位置,满足最大根堆的要求
            A[k] = A[i];
            k = i;
            i = k/2; //继续向上寻找并调整,直至满足最大根堆要求
        }
        A[k] = Tmp; //
    }
    void AdjustDown(ElementType A[],int k,int len) //该方法用于堆的初始化
    {
        int Tmp = A[k];
        for(int i = 2*k; i <= len; i*=2) //向下筛选
        {
            if(i < len && A[i] < A[i+1]) i++;
            if(Tmp > A[i]) break;
            else
            {
                A[k] = A[i];
                k = i;
            }
        }
        A[k] = Tmp;
    }
    void BuildMaxHeap(ElementType A[],int len)
    {
        for(int i= len/2 ; i > 0; i--)
        {
            AdjustDown(A,i,len);
        }
    }
    void PrintfElementArray(ElementType A[],int len)
    {
        for(int i=1;i<=len;i++)
        {
            printf("%d%c",A[i],i==len?'
    ':' ');
        }
    }
    int main()
    {
        ElementType A[] = {0,2,7,26,25,19,17,90,3};
        ElementType B[ARR_SIZE];
        BuildMaxHeap(A,8);
        PrintfElementArray(A,8);
        for(int i=0;i<=8;i++)
        {
            B[i] = A[i];
        }
        B[9] = 44;//插入44
        AdjustUp(B,9,9);
        PrintfElementArray(B,9);
    }
    
    
    参考文档

    [1] 数据结构堆可视化:https://visualgo.net/zh/heap

  • 相关阅读:
    QT4.7.1 + VS2008 + QT Designer开发流程心得
    SharePoint 2010 托管元数据Bug (跟邮件提醒功能相关.小bug,大问题)
    SharePoint 2010 技巧系列: 控制Ribbon菜单权限(SiteActions的例子)
    发布一个SharePoint 2010 工具(复制,移动文件和文件夹)
    SHarePoint 2010 技巧 列验证 (column Validation)
    SharePoint 2010系列: 教你如何创建Internet 站点一 (设计母版页)
    SharePoint2010 技巧系列:快速开发Ribbon
    SharePoint 2010 技巧: 限制People Picker搜索非站点集内的用户
    SharePoint 2010 技巧系列 启用文档库接收邮件功能
    SharePoint 2010 技巧系列: 文档管理的自动分发功能
  • 原文地址:https://www.cnblogs.com/masterchd/p/13737344.html
Copyright © 2011-2022 走看看