【数据结构】二叉树顺序结构及实现(一)

简介: 【数据结构】二叉树顺序结构及实现(一)

前言


 在前面的学习中,我们实现了栈与队列的实现。今天我们就通过顺序表来实现二叉树!


a004f90e77cc5b5c625c6fd2b3684e42_1304f5049c4f4a408a4df6230bf1cde5.png


一. 二叉树的顺序结构


我们如何让顺序表和二叉树建立联系呢?


我们可以先对二叉树的每个结点进行编号,通过数组的连续排列建立以下联系:


5f83a0c7ebcc85aa0cdf4953d2caeab2_be49312fb955419db247f7bc0fb63da4.png


这样我们就可以通过数组的下标来模拟实现二叉树了!


5f83a0c7ebcc85aa0cdf4953d2caeab2_be49312fb955419db247f7bc0fb63da4.png


但是普通的二叉树是不适合用数组来存储的,因为可能会存在大量的空间浪费。


cde7747ff8a2144d593b8f607fae43b0_18b40ce79f1347b8b84630a6bb98756d.png


所以我们的数组存储表示二叉树只适合完全二叉树。


二.堆的概念及结构


b1908d8d19bc5ba3453010ffe35f6ed7_d0fe48ae29b94f44a331bd4bc03821a7.png


简单的来说,堆就是一颗完全二叉树,并且有以下性质:


堆中某个节点的值总是不大于或不小于其父节点的值;

堆总是一棵完全二叉树。

其中分为小根堆和大根堆:


小根堆:

树中所有父亲都小于等于孩子:


f6d2401f676bec91fd353776e9b4209f_f89d367936324d10b7330b3fbc619dfb.png


大根堆:

树中所有父亲都大于等于孩子


6b213da452199673d16be32262766886_b2140a0239354853b310ba2312b19d0d.png


注意:

在数据结构里面我们所学的栈,堆都是一种数据结构,他们与操作系统

中的栈和堆是两回事,一个是数据结构,一个是操作系统相关的知识,一定不要搞混淆!


三.堆的实现:


typedef int HPDataType;
typedef struct Heap
{
  HPDataType* a;
  int size;
  int capacity;
}HP;
void HeapInit(HP* php);
void HeapDestroy(HP* php);
void HeapPush(HP* php, HPDataType x);
void HeapPop(HP* php);
HPDataType HeapTop(HP* php);
bool HeapEmpty(HP* php);
int HeapSize(HP* php);
void AdjustUp(HPDataType* a, int child);
void AdjustDown(HPDataType* a, int n, int parent);




1.堆的插入(向上调整算法):


 先插入一个数到数组的尾上,再进行向上调整算法,直到满足堆。


向上调整算法的条件是:

除了child结点,之前的结点都是堆


e45e8f8f926f40994c38127d9d70b3d5_ad740e4e1f904fb9ad8b531e1b8043e4.png


代码实现:


void AdjustUp(HPDataType* a, int child)
{
  int parent = (child - 1) / 2;
  while (child>0)
  {
  if (a[child] > a[parent])
  {
    swap(&a[child],&a[parent]);
    child = parent;
    parent = (child - 1) / 2;
  }
  else
  {
    break;
  }
  }
}
void HeapPush(HP* php, HPDataType x)
{
  assert(php);
  if (php->capacity == php->size)
  {
  HPDataType* ptr = (HPDataType*)realloc(php->a, sizeof(HPDataType) * php->capacity * 2);
  if (ptr == NULL)
  {
    perror("realloc::fail");
    return;
  }
  php->a = ptr;
  php->capacity *= 2;
  }
  php->a[php->size] = x;
  php->size++;
  AdjustUp(php->a, php->size-1);
}



2.堆的删除(向下调整算法):


 在这里删除堆是指删除堆顶的数据,因为删除堆尾元素没有什么实际的意义。将堆顶的数据与最后一个数据一换,然后删除数组最后一个数据,再进行向下调整算法。


向下调整算法的条件是:


左右子树都为堆!


df61abfd9fdb0fbfec32b6e4cbe12961_0ae7df0eef554abdaece48964d9b6ad9.png


代码实现:


void HeapPop(HP* php)
{
  assert(php);
  assert(!HeapEmpty(php));
  // 删除数据
  Swap(&php->a[0], &php->a[php->size - 1]);
  php->size--;
  AdjustDown(php->a, php->size, 0);
}
void AdjustDown(HPDataType* a, int n, int parent)
{
  int child = parent * 2 + 1;
  while (child < n)
  {
  // 选出左右孩子中大的那一个
  if (child + 1 < n && a[child+1] > a[child])
  {
    ++child;
  }
  if (a[child] > a[parent])
  {
    Swap(&a[child], &a[parent]);
    parent = child;
    child = parent * 2 + 1;
  }
  else
  {
    break;
  }
  }
}



3.堆的构建:


这里建议把后面的堆排序看了在来看这段代码:


void HeapInitArray(HP* php, int* a, int n)
{
  assert(php);
  php->a = (HPDataType*)malloc(sizeof(HPDataType) * n);
  if (php->a == NULL)
  {
  perror("malloc fail");
  return;
  }
  php->size = n;
  php->capacity = n;
  // 建堆
  for (int i = (n-2)/2; i >= 0; --i)
  {
  AdjustDown(php->a, php->size, i);
  }
}



这里的意思是给你一个属数组,这个数组逻辑上可以看做一颗完全二叉树,但是还不是一个堆,现在我们通过算法,把它构建成一个堆。

目录
相关文章
|
15天前
|
Java C++
【C++数据结构——树】二叉树的基本运算(头歌实践教学平台习题)【合集】
本关任务:编写一个程序实现二叉树的基本运算。​ 相关知识 创建二叉树 销毁二叉树 查找结点 求二叉树的高度 输出二叉树 //二叉树节点结构体定义 structTreeNode{ intval; TreeNode*left; TreeNode*right; TreeNode(intx):val(x),left(NULL),right(NULL){} }; 创建二叉树 //创建二叉树函数(简单示例,手动构建) TreeNode*create
39 12
|
15天前
|
C++
【C++数据结构——树】二叉树的性质(头歌实践教学平台习题)【合集】
本文档介绍了如何根据二叉树的括号表示串创建二叉树,并计算其结点个数、叶子结点个数、某结点的层次和二叉树的宽度。主要内容包括: 1. **定义二叉树节点结构体**:定义了包含节点值、左子节点指针和右子节点指针的结构体。 2. **实现构建二叉树的函数**:通过解析括号表示串,递归地构建二叉树的各个节点及其子树。 3. **使用示例**:展示了如何调用 `buildTree` 函数构建二叉树并进行简单验证。 4. **计算二叉树属性**: - 计算二叉树节点个数。 - 计算二叉树叶子节点个数。 - 计算某节点的层次。 - 计算二叉树的宽度。 最后,提供了测试说明及通关代
38 10
|
16天前
|
存储 算法 测试技术
【C++数据结构——树】二叉树的遍历算法(头歌教学实验平台习题) 【合集】
本任务旨在实现二叉树的遍历,包括先序、中序、后序和层次遍历。首先介绍了二叉树的基本概念与结构定义,并通过C++代码示例展示了如何定义二叉树节点及构建二叉树。接着详细讲解了四种遍历方法的递归实现逻辑,以及层次遍历中队列的应用。最后提供了测试用例和预期输出,确保代码正确性。通过这些内容,帮助读者理解并掌握二叉树遍历的核心思想与实现技巧。
39 2
|
29天前
|
数据库
数据结构中二叉树,哈希表,顺序表,链表的比较补充
二叉搜索树,哈希表,顺序表,链表的特点的比较
数据结构中二叉树,哈希表,顺序表,链表的比较补充
|
2月前
|
机器学习/深度学习 存储 算法
数据结构实验之二叉树实验基础
本实验旨在掌握二叉树的基本特性和遍历算法,包括先序、中序、后序的递归与非递归遍历方法。通过编程实践,加深对二叉树结构的理解,学习如何计算二叉树的深度、叶子节点数等属性。实验内容涉及创建二叉树、实现各种遍历算法及求解特定节点数量。
117 4
|
2月前
|
存储 搜索推荐 算法
【数据结构】树型结构详解 + 堆的实现(c语言)(附源码)
本文介绍了树和二叉树的基本概念及结构,重点讲解了堆这一重要的数据结构。堆是一种特殊的完全二叉树,常用于实现优先队列和高效的排序算法(如堆排序)。文章详细描述了堆的性质、存储方式及其实现方法,包括插入、删除和取堆顶数据等操作的具体实现。通过这些内容,读者可以全面了解堆的原理和应用。
129 16
|
2月前
|
C语言
【数据结构】二叉树(c语言)(附源码)
本文介绍了如何使用链式结构实现二叉树的基本功能,包括前序、中序、后序和层序遍历,统计节点个数和树的高度,查找节点,判断是否为完全二叉树,以及销毁二叉树。通过手动创建一棵二叉树,详细讲解了每个功能的实现方法和代码示例,帮助读者深入理解递归和数据结构的应用。
180 8
|
3月前
|
存储 算法 关系型数据库
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
这篇文章主要介绍了多路查找树的基本概念,包括二叉树的局限性、多叉树的优化、B树及其变体(如2-3树、B+树、B*树)的特点和应用,旨在帮助读者理解这些数据结构在文件系统和数据库系统中的重要性和效率。
40 0
数据结构与算法学习二一:多路查找树、二叉树与B树、2-3树、B+树、B*树。(本章为了解基本知识即可,不做代码学习)
|
3月前
|
存储 算法
探索数据结构:分支的世界之二叉树与堆
探索数据结构:分支的世界之二叉树与堆
|
3月前
探索顺序结构:栈的实现方式
探索顺序结构:栈的实现方式

热门文章

最新文章