Heap

举报
tianchou 发表于 2023/11/14 19:38:33 2023/11/14
【摘要】 本文描述了数据结构Heap的常用操作和例题,并配备丰富的注释和代码

title: 【Heap】
date: 2023-09-28 20:15:27
tags: 数据结构

定义

==采用**数组存储完全二叉树**==

image-20230916123313335

image-20221019101952011

注意:data[0]用来存放==哨兵==

分类

最小堆(MinHeap):任一结点的data小于其所有子树结点的data

最大堆(MinHeap):任一结点的data大于其所有子树结点的dat

image-20230916123453824

操作(以MaxHeap为例)

对象集

typedef struct HeapNode 
{
	ElementType data[Maxsize];
    int size;
}* MaxHeap;

下滤筛选

void HeapAdjust(MaxHeap H,int s)
{
    ElementType t = H->data[s];
    for( int i=2*s; i<=n; i*=2)
    {
        if(i < H->size && H->data[i] < H->data[i+1])	//i < H->size说明H->data[i+1]存在
            i++;
        if(t >= H->data[i])		break;
        else	{	H->data[s]=H->data[i];	s=i;	}
    }
    H->data[s]=t;
}

下滤:用于删除堆顶元素后,调整堆

上滤筛选

void HeapAdjust(MaxHeap H,int s)
{
    ElementType t = H->data[s];
    for( int i=s/2; i>=1; i/=2)
    {
        if(H->data[i] >= t)		break;
        else	{	H->data[s]=H->data[i];		s=i;	}
    }
    H->data[s]=t;
}

上滤:用于向堆中插入一个元素

最大堆的初始化创建

MaxHeap CreatHeap(int Max)
{
    MaxHeap H=(MaxHeap)malloc(sizeof((struct HeapNode)));
    H->data[0]=MaxData;	//INT_MAX
    H->size=0;
    return H;
}

最大堆的插入

void Insert(MaxHeap H,ElementType t)
{
    int i;
    if(H->size>=Maxsize)
        return;
    for(i=++H->size;t>H->data[i/2];i/=2)
        H->data[i]=H->data[i/2];
    H->data[i]=t;
}

注:H->data[0]是哨兵,它不会小于堆中的最大元素,其作用:控制循环结束。

最大堆的删除

步骤

这里写图片描述

删除并且返回根节点(最大值)

代码

ElementType Delete(MaxHeap H)
{
    if(H->size==0)
        return NULL;
    ElementType max=H->data[1];	//取出根节点最大值,最后return
    
   /* 用最大堆中最后一个元素从根结点开始向上过滤下层结点 */ 
    ElementType t=H->data[H->size--];
    int parent,child;
    for(parent=1;parent*2<=H->size;parent=child)	//若parent*2>H->size说明parent没有左儿子,也就更没有右儿子
    {
        child=parent*2;		//child指向左右儿子最大的那个,先初始赋值左儿子
        if((child!=H->size)&&H->data[child] < H->data[child+1])	//child!=H->size说明有右儿子
            child++;	
        if(t>=H->data[child])	break;
        else
            H->data[parent]=H->data[child];
    }
    H->data[parent]=t;
    return max;
}
  • 第10行parent*=2错误,必须是parent=child,作用是parent索引变成儿子索引,向下交换
  • 第8行~~data[H->size]~~错误,必须是data[H->size--]

最大堆的建立

法一:

步骤:
(1)调用Insert函数,将N个元素一个个相继插入到一个初始为空的堆Heap中去。
(2)其时间复杂度为O(N logN)。
MaxHeap BuildHeap ()
{
    MaxHeap H=(MaxHeap)malloc(sizeof((struct HeapNode)));
    H->data[0]=MaxData;		//INT_MAX
    H->size=0;
    ElementType t;
    for(int i=0;i<n;i++)
    {
        cin>>t;
        Insert(H,t);
    }
    return H;
}

法二:

步骤:
(1)将N个元素按输入顺序存入,先满足完全二叉树的结构特性
(2)调整各结点位置,以满足最大堆的有序特性。
代码
MaxHeap BuildHeap ()
{
    MaxHeap H=(MaxHeap)malloc(sizeof((struct HeapNode)));
    H->data[0]=MaxData;		//INT_MAX
    H->size=0;
    
    ElementType t;
    for(int i=1;i<=n;i++)
    {
        cin>>H->data[i];
        if
            
    }
    return H;
}
【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。