当前位置: 首页 > news >正文

《数据结构:顺序实现二叉树》

文章目录

    • 一、树
        • 1、树的结构与概念
        • 2、树相关术语
    • 二、二叉树
        • 1、概念与结构
        • 2、满二叉树
        • 3、完全二叉树
    • 三、顺序二叉树存储结构
    • 四、实现顺序结构二叉树
        • 1、堆的概念与结构
        • 2、堆的实现
        • 3、堆的排序

一、树

1、树的结构与概念

树是一种非线性的数据结构,它是由n(n>=0)个有限结点组成的一个具有层次关系的集合。把它叫做树是因为它看起来像一颗倒挂的树,也就是说它是根朝上,而叶朝下的。

  • 有一个特殊的结点,称为根结点,根结点没有前驱结点。
  • 除根结点外,其余结点被分成 M(M>0)个互不相交的集合,其中每个集合又是一颗结构与树类似的子树。每颗自树的根结点有且只有一个 前驱,可以有0个或多个后继。因此树是递归定义的。

在这里插入图片描述

树形结构中,⼦树之间不能有交集,否则就不是树形结构

非树形结构:
在这里插入图片描述

  • 子树是不相交的
  • 除根结点外,每个结点有且仅有一个父节点
  • 一颗N个结点的树有N - 1条边
2、树相关术语

在这里插入图片描述

  • ⽗结点/双亲结点:若⼀个结点含有⼦结点,则这个结点称为其⼦结点的⽗结点; 如上图:A是B的⽗结点
  • ⼦结点/孩⼦结点:⼀个结点含有的⼦树的根结点称为该结点的⼦结点; 如上图:B是A的孩⼦结点
  • 结点的度:⼀个结点有⼏个孩⼦,他的度就是多少;⽐如A的度为6,F的度为2,K的度为0
  • 树的度:⼀棵树中,最⼤的结点的度称为树的度; 如上图:树的度为 6
  • 叶⼦结点/终端结点:度为 0 的结点称为叶结点; 如上图: B、C、H、I… 等结点为叶结点
  • 分⽀结点/⾮终端结点:度不为 0 的结点; 如上图: D、E、F、G… 等结点为分⽀结点
  • 分⽀结点/⾮终端结点:度不为 0 的结点; 如上图: D、E、F、G… 等结点为分⽀结点
  • 结点的层次:从根开始定义起,根为第 1 层,根的⼦结点为第 2 层,以此类推;
  • 树的⾼度或深度:树中结点的最⼤层次; 如上图:树的⾼度为 4
  • 结点的祖先:从根到该结点所经分⽀上的所有结点;如上图: A 是所有结点的祖先
  • 路径:⼀条从树中任意节点出发,沿⽗节点-⼦节点连接,达到任意节点的序列;⽐如A到Q的路径为:A-E-J-Q;H到Q的路径H-D-A-E-J-Q
  • ⼦孙:以某结点为根的⼦树中任⼀结点都称为该结点的⼦孙。如上图:所有结点都是A的⼦孙
  • 森林:由 m(m>0) 棵互不相交的树的集合称为森林;

二、二叉树

1、概念与结构

树形结构中,我们最常⽤的就是⼆叉树,⼀棵⼆叉树是结点的⼀个有限集合,该集合由⼀个根结点加上两棵别称为左⼦树和右⼦树的⼆叉树组成或者为空。

在这里插入图片描述

二叉树具备以下特点:

  • 1.⼆叉树不存在度⼤于 2 的结点
    1. ⼆叉树的⼦树有左右之分,次序不能颠倒,因此⼆叉树是有序树

注意:对于任意的⼆叉树都是由以下⼏种情况复合⽽成的

在这里插入图片描述

2、满二叉树

⼀个⼆叉树,如果每⼀个层的结点数都达到最⼤值,则这个⼆叉树就是满⼆叉树。也就是说,如果⼀个⼆叉树的层数为 K ,且结点总数是 2k − 1 ,则它就是满⼆叉树。

在这里插入图片描述

3、完全二叉树

完全⼆叉树是效率很⾼的数据结构,完全⼆叉树是由满⼆叉树⽽引出来的。对于深度为 K 的,有 n 个结点的⼆叉树,当且仅当其每⼀个结点都与深度为K的满⼆叉树中编号从 1 ⾄ n 的结点⼀⼀对应时称之为完全⼆叉树。要注意的是满⼆叉树是⼀种特殊的完全⼆叉树。

在这里插入图片描述

二叉树性质

  • 1)若规定根结点的层数为 1 ,则⼀棵⾮空⼆叉树的第i层上最多有 2i−1 个结点
  • 2)若规定根结点的层数为 1 ,则深度为 h 的⼆叉树的最⼤结点数是 2h − 1
  • 3)若规定根结点的层数为 1 ,具有 n 个结点的满⼆叉树的深度 h = log ⁡ 2 ( n + 1 ) \log_2 (n+1) log2(n+1) ( log以2为底, n+1 为对数)

三、顺序二叉树存储结构

顺序结构存储就是使⽤数组来存储,⼀般使⽤数组只适合表⽰完全⼆叉树,因为不是完全⼆叉树会有空间的浪费,完全⼆叉树更适合使⽤顺序结构存储。

在这里插入图片描述

现实中我们通常把堆(⼀种⼆叉树)使⽤顺序结构的数组来存储,需要注意的是这⾥的堆和操作系统虚拟进程地址空间中的堆是两回事,⼀个是数据结构,⼀个是操作系统中管理内存的⼀块区域分段。

四、实现顺序结构二叉树

⼀般堆使⽤顺序结构的数组来存储数据,堆是⼀种特殊的⼆叉树,具有⼆叉树的特性的同时,还具备其他的特性。

1、堆的概念与结构

如果有⼀个关键码的集合K={ k 0 , k 1 , ⋯ , k n − 1 k_0, k_1, \cdots, k_{n-1} k0,k1,,kn1,把它的所有元素按完全⼆叉树的顺序存储⽅式存储,在⼀个⼀维数组中,并满⾜: K i K_i Ki<= K 2 ∗ i + 1 K_{2*i+1} K2i+1,i = 0、1、2… ,则称为⼩堆(或⼤堆)。将根结点最⼤的堆叫做最⼤堆或⼤根堆,根结点最⼩的堆叫做最⼩堆或⼩根堆。

在这里插入图片描述

堆具有以下性质

  • 堆中某个结点的值总是不⼤于或不⼩于其⽗结点的值;
  • 堆总是⼀棵完全⼆叉树。

顺序二叉树性质

  • 对于具有 n 个结点的完全⼆叉树,如果按照从上⾄下从左⾄右的数组顺序对所有结点从0 开始编号,则对于序号为 i 的结点有:
    1. 若 i>0 , i 位置结点的双亲序号: (i-1)/2 ; i=0 , i 为根结点编号,⽆双亲结点
    1. 若 2i+1<n ,左孩⼦序号: 2i+1 , 2i+1>=n 否则⽆左孩⼦
    1. 若 2i+2<n ,右孩⼦序号: 2i+2 , 2i+2>=n 否则⽆右孩⼦
2、堆的实现

堆的底层结构为数组,因此定义堆的结构为:

#pragma once#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include<stdbool.h>typedef int HPDateType;typedef struct Heap
{HPDateType* arr;int capacity;int size;
}HP;//初始化
void HPInit(HP* php);//销毁
void HPDesTroy(HP* php);//堆尾插入数据
void HPPush(HP* php, HPDateType x);//向上调整
void AdjustUp(HPDateType* arr, int child);//删除堆顶数据
void HPPop(HP* php);//向下调整
void AdjustDown(HPDateType* arr, int parent,int n);//取堆顶数据
HPDateType HPTop(HP* php);//判断堆是否为空
bool HPEmpty(HP* php);

堆的函数实现:

#include"Heap.h"//初始化
void HPInit(HP* php)
{assert(php != NULL);php->arr = NULL;php->capacity = php->size = 0;
}//销毁
void HPDesTroy(HP* php)
{assert(php != NULL);free(php->arr);php->arr = NULL;php->capacity = php->size;
}//交换
void swap(HPDateType* x, HPDateType* y)
{HPDateType tmp = *x;*x = *y;*y = tmp;
}//向上调整
void AdjustUp(HPDateType* arr, int child)
{assert(arr != NULL);int parent = (child - 1) / 2;while (arr[parent] > arr[child] && child > 0){swap(&arr[parent], &arr[child]);child = parent;parent = (child - 1) / 2;}
}//插入数据
void HPPush(HP* php, HPDateType x)
{assert(php != NULL);//判断空间够不够if (php->capacity == php->size){//增容int newcapacity = php->capacity == 0 ? 4 : 2 * php->capacity;HPDateType* tmp = (HPDateType*)realloc(php->arr, newcapacity*sizeof(HPDateType));if (tmp == NULL){perror("realloc fail");exit(1);}php->arr = tmp;tmp = NULL;php->capacity = newcapacity;}php->arr[php->size++] = x;AdjustUp(php->arr, php->size - 1);
}//删除数据
void HPPop(HP* php)
{assert(php != NULL);assert(php->size > 0);swap(&php->arr[0], &php->arr[php->size - 1]);php->size--;AdjustDown(php->arr, 0,php->size);
}//向下调整
void AdjustDown(HPDateType* arr, int parent,int n)
{assert(arr != NULL);int child = (parent * 2) + 1;while (child < n){if (child + 1 < n && arr[child + 1] < arr[child]){child++;}if (arr[child] < arr[parent]){swap(&arr[child], &arr[parent]);parent = child;child = parent * 2 + 1;}else{break;}}
}//取堆顶数据
HPDateType HPTop(HP* php)
{assert(php != NULL);assert(php->size > 0);return php->arr[0];
}//判断堆是否为空
bool HPEmpty(HP* php)
{assert(php != NULL);return php->size == 0;
}
3、堆的排序

运用堆排序时间复杂度大大减小

void HeapSort(int* arr, int n)
{//µint i = 0;int parent = 0;int child = 0;for (i = (n - 1) / 2; i >= 0; i--){parent = i;child = parent * 2 + 1;while (child < n){if (child + 1 < n && arr[child + 1] < arr[child]){child++;}if (arr[child] < arr[parent]){int tmp = arr[child];arr[child] = arr[parent];arr[parent] = tmp;parent = child;child = parent * 2 + 1;}else{break;}}}for (i = n - 1; i > 0; i--){parent = 0;child = i;int tmp = arr[child];arr[child] = arr[parent];arr[parent] = tmp;child = parent * 2 + 1;while (child < i){if (child + 1 < i && arr[child + 1] < arr[child]){child++;}if (arr[child] < arr[parent]){tmp = arr[child];arr[child] = arr[parent];arr[parent] = tmp;parent = child;child = parent * 2 + 1;}else{break;}}}
}

相关文章:

《数据结构:顺序实现二叉树》

文章目录 一、树1、树的结构与概念2、树相关术语 二、二叉树1、概念与结构2、满二叉树3、完全二叉树 三、顺序二叉树存储结构四、实现顺序结构二叉树1、堆的概念与结构2、堆的实现3、堆的排序 一、树 1、树的结构与概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff…...

【HarmonyOS】HarmonyOS NEXT学习日记:六、渲染控制、样式结构重用

【HarmonyOS】HarmonyOS NEXT学习日记&#xff1a;六、渲染控制、样式&结构重用 渲染控制包含了条件渲染和循环渲染&#xff0c;所谓条件渲染&#xff0c;即更具状态不同&#xff0c;选择性的渲染不同的组件。 而循环渲染则是用于列表之内的、多个重复元素组成的结构中。 …...

【防火墙】防火墙NAT、智能选路综合实验

实验拓扑 实验要求 7&#xff0c;办公区设备可以通过电信链路和移动链路上网(多对多的NAT&#xff0c;并且需要保留一个公网IP不能用来转换) 8&#xff0c;分公司设备可以通过总公司的移动链路和电信链路访问到Dmz区的http服务器 9&#xff0c;多出口环境基于带宽比例进行选路…...

VUE之---slot插槽

什么是插槽 slot 【插槽】&#xff0c; 是 Vue 的内容分发机制&#xff0c; 组件内部的模板引擎使用slot 元素作为承载分发内容的出口。slot 是子组件的一个模板标签元素&#xff0c; 而这一个标签元素是否显示&#xff0c; 以及怎么显示是由父组件决定的。 VUE中slot【插槽】…...

linux、windows、macos,命令终端清屏

文章目录 LinuxWindowsmacOS 在Linux、Windows和macOS的命令终端中&#xff0c;清屏的命令或方法各不相同。以下是针对这三种系统的清屏方法&#xff1a; Linux clear命令&#xff1a;这是最常用的清空终端屏幕的命令之一。在终端中输入clear命令后&#xff0c;屏幕上的所有内容…...

【RaspberryPi】树莓派Matlab/Simulink支持包安装与使用

官网支持与兼容性 Raspberry Pi Support from MATLAB - Hardware Support - MATLAB & Simulink Raspberry Pi Support from Simulink - Hardware Support - MATLAB & Simulink Matlab与树莓派兼容性 Simulink与树莓派兼容性 树莓派Matlab&Simulink RaspberryPi支…...

嵌入式人工智能(10-基于树莓派4B的DS1302实时时钟RTC)

1、实时时钟&#xff08;Real Time Clock&#xff09; RTC&#xff0c;全称为实时时钟&#xff08;Real Time Clock&#xff09;&#xff0c;是一种能够提供实时时间信息的电子设备。RTC通常包括一个计时器和一个能够记录日期和时间的电池。它可以独立于主控芯片工作&#xff…...

C++ | Leetcode C++题解之第275题H指数II

题目&#xff1a; 题解&#xff1a; class Solution { public:int hIndex(vector<int>& citations) {int n citations.size();int left 0, right n - 1;while (left < right) {int mid left (right - left) / 2;if (citations[mid] > n - mid) {right m…...

编写DockerFile

将自己的项目或者环境通过Docker部署到服务器需要一下几个步骤&#xff1a; 打包项目或者环境 编写Dockerfile文件 运行Dockerfile文件&#xff0c;构建DockerImages镜像&#xff0c;将DockerImages存入DockerHub或者存入阿里云镜像仓库 服务器pull下DockerImages镜像&#…...

TCP并发服务器多线程

1.创建线程‐‐pthread_create int pthread_create( pthread_t *thread, // 线程 ID 无符号长整型 const pthread_attr_t *attr, // 线程属性&#xff0c; NULL void *(*start_routine)(void *), // 线程处理函数 void *arg); // 线程处理函数 参数&#xff1a; pthrea…...

技术速递|C# 13:探索最新的预览功能

作者&#xff1a;Kathleen Dollard 排版&#xff1a;Alan Wang C# 13 已初具雏形&#xff0c;其新特性侧重于灵活性、性能以及使您最喜欢的功能在日常中变得更容易使用。我们以公开的方式构建 C#&#xff0c;在今年的 Microsoft Build 大会上&#xff0c;我们会让您一睹 C# 13 …...

Python设计模式:巧用元类创建单例模式!

✨ 内容&#xff1a; 今天我们来探讨一个高级且实用的Python概念——元类&#xff08;Metaclasses&#xff09;。元类是创建类的类&#xff0c;它们可以用来控制类的行为。通过本次练习&#xff0c;我们将学习如何使用元类来实现单例模式&#xff0c;确保某个类在整个程序中只…...

构建自主可控的工业操作系统,筑牢我国工业安全堡垒

构建自主可控的工业操作系统&#xff0c;筑牢我国工业安全堡垒&#xff0c;鸿道(Intewell)操作系统为国家工业发展保驾护航。 7月19日&#xff0c;全球多地安装微软操作系统的电脑设备出现大规模宕机&#xff0c;导致“蓝屏”现象&#xff0c;严重影响了航空、铁路、医疗、金…...

WPF串口通讯程序

目录 一 设计原型 二 后台源码 一 设计原型 二 后台源码 using HardwareCommunications; using System.IO.Ports; using System.Windows;namespace PortTest {/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainW…...

汽车技术智能化程度不断提升,线束可靠性如何设计?

随着汽车技术的高速发展&#xff0c;汽车自动化、智能化程度的逐步提高&#xff0c;人们对汽车的安全性、舒适性、娱乐性等要求也不断提高&#xff0c;加上汽车节能减排法规的不断严峻&#xff0c;整车电气设备不断增加&#xff0c;作为连接汽车各种电器设备“神经网络”的整车…...

实现Nginx的反向代理和负载均衡

一、反向代理和负载均衡简介 1.1、反向代理 反向代理(reverse proxy)指:以代理服务器来接受Internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给Internet上请求连接的客户端。此时代理服务器对外就表现为一个反向代理服务器。 反向代…...

【算法】子集

难度&#xff1a;中等 题目&#xff1a; 给你一个整数数组 nums &#xff0c;数组中的元素 互不相同 。返回该数组所有可能的 子集&#xff08;幂集&#xff09;。 解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 示例 1&#xff1a; 输入&#xff1a;nums [1,…...

Web前端:HTML篇(一)

HTML简介&#xff1a; 超文本标记语言&#xff08;英语&#xff1a;HyperText Markup Language&#xff0c;简称&#xff1a;HTML&#xff09;是一种用于创建网页的标准标记语言。 您可以使用 HTML 来建立自己的 WEB 站点&#xff0c;HTML 运行在浏览器上&#xff0c;由浏览器…...

ActiViz中的选择点vtkWorldPointPicker

文章目录 1. vtkWorldPointPicker简介2. 类的位置和继承关系3. 选择机制4. 返回的信息5. 选择的条件和参数6. 与屏幕空间选择器的比较7. 性能特征8. 应用场景9. 与其他vtk选择器的集成10. 完整示例总结1. vtkWorldPointPicker简介 vtkWorldPointPicker是Visualization Toolkit…...

如何开启或者关闭 Windows 安全登录?

什么是安全登录 什么是 Windows 安全登录呢&#xff1f;安全登录是 Windows 附加的一个组件&#xff0c;它可以在用户需要登录的之前先将登录界面隐藏&#xff0c;只有当用户按下 CtrlAltDelete 之后才出现登录屏幕&#xff0c;这样可以防止那些模拟登录界面的程序获取密码信息…...

网络编程(Modbus进阶)

思维导图 Modbus RTU&#xff08;先学一点理论&#xff09; 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议&#xff0c;由 Modicon 公司&#xff08;现施耐德电气&#xff09;于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

Java如何权衡是使用无序的数组还是有序的数组

在 Java 中,选择有序数组还是无序数组取决于具体场景的性能需求与操作特点。以下是关键权衡因素及决策指南: ⚖️ 核心权衡维度 维度有序数组无序数组查询性能二分查找 O(log n) ✅线性扫描 O(n) ❌插入/删除需移位维护顺序 O(n) ❌直接操作尾部 O(1) ✅内存开销与无序数组相…...

WEB3全栈开发——面试专业技能点P2智能合约开发(Solidity)

一、Solidity合约开发 下面是 Solidity 合约开发 的概念、代码示例及讲解&#xff0c;适合用作学习或写简历项目背景说明。 &#x1f9e0; 一、概念简介&#xff1a;Solidity 合约开发 Solidity 是一种专门为 以太坊&#xff08;Ethereum&#xff09;平台编写智能合约的高级编…...

鸿蒙(HarmonyOS5)实现跳一跳小游戏

下面我将介绍如何使用鸿蒙的ArkUI框架&#xff0c;实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

Kubernetes 节点自动伸缩(Cluster Autoscaler)原理与实践

在 Kubernetes 集群中&#xff0c;如何在保障应用高可用的同时有效地管理资源&#xff0c;一直是运维人员和开发者关注的重点。随着微服务架构的普及&#xff0c;集群内各个服务的负载波动日趋明显&#xff0c;传统的手动扩缩容方式已无法满足实时性和弹性需求。 Cluster Auto…...

大数据驱动企业决策智能化的路径与实践

&#x1f4dd;个人主页&#x1f339;&#xff1a;慌ZHANG-CSDN博客 &#x1f339;&#x1f339;期待您的关注 &#x1f339;&#x1f339; 一、引言&#xff1a;数据驱动的企业竞争力重构 在这个瞬息万变的商业时代&#xff0c;“快者胜”的竞争逻辑愈发明显。企业如何在复杂环…...

未授权访问事件频发,我们应当如何应对?

在当下&#xff0c;数据已成为企业和组织的核心资产&#xff0c;是推动业务发展、决策制定以及创新的关键驱动力。然而&#xff0c;未授权访问这一隐匿的安全威胁&#xff0c;正如同高悬的达摩克利斯之剑&#xff0c;时刻威胁着数据的安全&#xff0c;一旦触发&#xff0c;便可…...

RLHF vs RLVR:对齐学习中的两种强化方式详解

在语言模型对齐&#xff08;alignment&#xff09;中&#xff0c;强化学习&#xff08;RL&#xff09;是一种重要的策略。而其中两种典型形式——RLHF&#xff08;Reinforcement Learning with Human Feedback&#xff09; 与 RLVR&#xff08;Reinforcement Learning with Ver…...

C#最佳实践:为何优先使用as或is而非强制转换

C#最佳实践&#xff1a;为何优先使用as或is而非强制转换 在 C# 的编程世界里&#xff0c;类型转换是我们经常会遇到的操作。就像在现实生活中&#xff0c;我们可能需要把不同形状的物品重新整理归类一样&#xff0c;在代码里&#xff0c;我们也常常需要将一个数据类型转换为另…...