二叉树——堆(C语言实现)

简介: 二叉树——堆(C语言实现)

小堆的结构与初始化

小堆的结构是子节点不小于父节点,兄弟结点没有顺序,并且总是完全二叉树。

逻辑结构是这样的:

物理储存我们用顺序表来储存:

首先从结点的祖先10开始,放进顺序表中,然后是他的子节点15和20,再往下访问也是访问15和20的子节点,分别是30,20,25,90,按照这个规律放进顺序表中就可以了。

[10,15,20,30,20,25,90,40,30,70];

首先创建一个顺序表的结构体

typedef int SD;//方便以后更改数组的数据类型
typedef struct pile
{
  SD* a;//数组
  int size;//数组有效值的长度
  int capacity;//数组容量大小
}pile;

初始化

void initialize(pile* hp)//初始化
{
  hp->a = NULL;
  hp->capacity = hp->size = 0;
}

堆的销毁,空判定,打印

销毁

void HeapDestory(pile* hp)//销毁
{
  free(hp->a);
  hp->a = NULL;
  hp->capacity = hp->size = 0;
}

判断是否为空

空返回0,非空返回非0.

int HeapEmpty(pile* hp)//判断空
{
  return hp->size;
}

打印

这里只打印整理后的数组:

void Pintf(pile* hp)//打印
{
  assert(hp);
  int i = 0;
  for (i = 0; i < hp->size; i++)
  {
    printf("%d ", hp->a[i]);
  }
}

插入,删除

插入

物理结构是在顺序表中末尾插入一个数据。

比如说我们插入一个5.

但是如果插入之后就不是小堆的结构了,祖先不小于等于新增元素,所以我们需要将5向上调整。(红线是调整顺序)

调成之后是这样的:

void swap(SD* p1,SD* p2)//交换数据
{
  SD p = *p1;
  *p1 = *p2;
  *p2 = p;
}
void HeapPush(pile* hp, SD x)//插入
{
  assert(hp);
  if (hp->capacity == hp->size)
  {
    int sum = hp->capacity == 0 ? 4 : hp->capacity * 2;
    SD* p = (SD* )realloc(hp->a, sum * sizeof(SD));
    if (p == NULL)
    {
      perror("realloc fail");
      exit(-1);
    }
    hp->a = p;
    hp->capacity = sum;
  }
  hp->a[hp->size] = x;//插入数据
  hp->size++;//记录数组的有效长度
  int child = hp->size - 1;//新插入的元素,元素的下标
  int parent = (child - 1) / 2;//新插入的元素的父节点,父节点的下标
  while (child > 0)//孩子的下标如果等于0就说明到堆顶了
  {
    if (hp->a[child] < hp->a[parent])//如果孩子比父节点小就交换
    {
      swap(&(hp->a[child]), &(hp->a[parent]));//交换
      child = parent;
      parent = (child - 1) / 2;
    }
    else
    {
      break;//如果不成立就说明已经是小堆了
    }
  }
}

删除

删除第一个元素。

因为要保持原来小堆的形态,所以要让10到删除的那个位置,20不行,然后是15补刀10的位置,以此类推。(向下调整算法)

最后变成了这样:

代码是这个操作我们需要将头和尾先交换一下,然后删除尾再向下调整。

void HeapPop(pile* hp)//删除
{
  assert(hp);
  assert(HeapEmpty(hp));//判断是否为空
  swap(&hp->a[hp->size - 1], &hp->a[0]);//交换首尾的位置
  hp->size-- ;//删掉末尾的数
  int parent = 0;//父结点下标
  int minchild = 2 * parent + 1;//表示最小的孩子,第一次先假设左孩子最小
  while (minchild < hp->size)//防止数组越界
  {
    if (minchild+1 < hp->size && hp->a[minchild + 1] < hp->a[minchild])//防止右孩子出界
    {
      minchild = minchild++;//如果右孩子比左孩子小就让右孩子等于最小
    }
    if (hp->a[minchild] < hp->a[parent])//判断是否需要向下调整
    {
      swap(&hp->a[minchild], &hp->a[parent]);
      parent = minchild;
      minchild = 2 * parent + 1;
    }
    else
    {
      break;
    }
  }
}


目录
打赏
0
0
0
0
18
分享
相关文章
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
168 16
|
4月前
|
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
235 8
数据结构基础详解(C语言): 二叉树的遍历_线索二叉树_树的存储结构_树与森林详解
本文从二叉树遍历入手,详细介绍了先序、中序和后序遍历方法,并探讨了如何构建二叉树及线索二叉树的概念。接着,文章讲解了树和森林的存储结构,特别是如何将树与森林转换为二叉树形式,以便利用二叉树的遍历方法。最后,讨论了树和森林的遍历算法,包括先根、后根和层次遍历。通过这些内容,读者可以全面了解二叉树及其相关概念。
100 6
数据结构基础详解(C语言): 树与二叉树的基本类型与存储结构详解
本文介绍了树和二叉树的基本概念及性质。树是由节点组成的层次结构,其中节点的度为其分支数量,树的度为树中最大节点度数。二叉树是一种特殊的树,其节点最多有两个子节点,具有多种性质,如叶子节点数与度为2的节点数之间的关系。此外,还介绍了二叉树的不同形态,包括满二叉树、完全二叉树、二叉排序树和平衡二叉树,并探讨了二叉树的顺序存储和链式存储结构。
C语言手撕实战代码_二叉树_构造二叉树_层序遍历二叉树_二叉树深度的超详细代码实现
这段代码和文本介绍了一系列二叉树相关的问题及其解决方案。其中包括根据前序和中序序列构建二叉树、通过层次遍历序列和中序序列创建二叉树、计算二叉树节点数量、叶子节点数量、度为1的节点数量、二叉树高度、特定节点子树深度、判断两棵树是否相似、将叶子节点链接成双向链表、计算算术表达式的值、判断是否为完全二叉树以及求二叉树的最大宽度等。每道题目均提供了详细的算法思路及相应的C/C++代码实现,帮助读者理解和掌握二叉树的基本操作与应用。
146 2
数据结构基础详解(C语言): 树与二叉树的应用_哈夫曼树与哈夫曼曼编码_并查集_二叉排序树_平衡二叉树
本文详细介绍了树与二叉树的应用,涵盖哈夫曼树与哈夫曼编码、并查集以及二叉排序树等内容。首先讲解了哈夫曼树的构造方法及其在数据压缩中的应用;接着介绍了并查集的基本概念、存储结构及优化方法;随后探讨了二叉排序树的定义、查找、插入和删除操作;最后阐述了平衡二叉树的概念及其在保证树平衡状态下的插入和删除操作。通过本文,读者可以全面了解树与二叉树在实际问题中的应用技巧和优化策略。
126 2
C语言的二叉树
1.树概念及结构 1.1树的概念 树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。 补充定义: 有一个特殊的结点,称为根结点,根节点没有前驱结点。除根节点外,其余结点被分成M(M>0)个互不相交的集合T1、T2、……、Tm,其中每一个集合Ti(1<= i <= m)又是一棵结构与树类似的子树。每棵子树的根结点有且只有一个前驱,可以有0个或多个后继。因此,树是递归定义的。 1.2 树的相关概念 节点的度:一个节点含有的子树的个数称为该节点的度; 如上图:A的为6 叶节点或终端
|
10月前
|
【C语言/数据结构】二叉树(层序遍历|判断完全二叉树|性质)
【C语言/数据结构】二叉树(层序遍历|判断完全二叉树|性质)
385 52
C语言实现二叉树的基本操作
二叉树是一种非常重要的数据结构。本文总结了二叉树的常见操作:二叉树的构建,查找,删除,二叉树的遍历(包括前序遍历、中序遍历、后序遍历、层次遍历),二叉搜索树的构造等。 1. 二叉树的构建   二叉树的基本构建方式为:添加一个节点,如果这是一棵空树,则将该节点作为根节点;否则按照从左到右、先左子树后右子树的顺序逐个添加节点。
1488 0
【C语言程序设计——函数】素数判定(头歌实践教学平台习题)【合集】
本内容介绍了编写一个判断素数的子函数的任务,涵盖循环控制与跳转语句、算术运算符(%)、以及素数的概念。任务要求在主函数中输入整数并输出是否为素数的信息。相关知识包括 `for` 和 `while` 循环、`break` 和 `continue` 语句、取余运算符 `%` 的使用及素数定义、分布规律和应用场景。编程要求根据提示补充代码,测试说明提供了输入输出示例,最后给出通关代码和测试结果。 任务核心:编写判断素数的子函数并在主函数中调用,涉及循环结构和条件判断。
75 23
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等