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

【数据结构】16 二叉树的定义,性质,存储结构(以及先序、后序、中序遍历)

二叉树

一个二叉树是一个有穷的结点集合。
它是由根节点和称为其左子树和右子树的两个不相交的二叉树组成的。
二叉树可具有以下5种形态。
在这里插入图片描述

性质

  1. 一个二叉树第i层的最大结点数为 2 i − 1 2^{i-1} 2i1, i ≥ 1 i \geq 1 i1
    每层最大结点可以对应完美二叉树(满二叉树),其所有分支结点都存在左右子树,并且所有叶结点都在同一层上。
    在这里插入图片描述
  2. 深度为k的二叉树有最大结点总数: 2 k − 1 2^k-1 2k1, k ≥ 1 k \geq 1 k1
    1 + 2 + . . . + 2 k − 1 = 2 k − 1 1 + 2 + ... +2^{k-1} = 2^k-1 1+2+...+2k1=2k1
  3. 对任何非空的二叉树 T n T_n Tn,若 n 0 n_0 n0是叶结点的个数, n 2 n_2 n2是度为2的非叶结点的个数,则: n 0 = n 2 + 1 n_0 = n_2 +1 n0=n2+1
    一颗二叉树:总结点数 = 叶节点 + 度为1的结点 + 度为2的结点
    又:总结点数 = 总边数+1
    且:总边数 = 2 ∗ 2* 2度为2的结点 + 度为1的结点
    由此得到: n 0 = n 2 + 1 n_0 = n_2 +1 n0=n2+1
  4. 具有n个结点的完全二叉树的深度k为 ⌊ l o g 2 n ⌋ + 1 \lfloor log_2{n} \rfloor +1 log2n+1
    (1) 满二叉树时:
    k深度: 结点 2 k − 1 2^k-1 2k1
    n = 2 k − 1 n = 2^k-1 n=2k1 k = l o g 2 n + 1 k = log_2{n+1} k=log2n+1
    (2)最底层只有一个结点
    k深度: 结点 2 k − 1 2^{k-1} 2k1
    解得: k = l o g 2 n + 1 k = log_2{n} +1 k=log2n+1
    l o g 2 ( n + 1 ) ≤ k ≤ l o g 2 n + 1 log_2{(n+1)} \leq k \leq log_2n +1 log2(n+1)klog2n+1
    则具有n个结点的完全二叉树的深度k为 ⌊ l o g 2 n ⌋ + 1 \lfloor log_2{n} \rfloor +1 log2n+1

存储结构

顺序存储

这种结构是川一组连续的存储单元(比如数组)存储二叉树结点的数据,结点的父子系是通过它们相对位置来反映的,而不需要任何附加的存储单元来存放指针,通常情况下顺序存储结构用于完全二叉树
具体实现是从树的根结点开始,从上层至下层,每层从左到右,依次给结点编号并将数据存放到一个数组的对应单元中。
结点C的父结点是结点B,它的左孩子是结点w,右孩子是结点K。C结点存储单元的下标是4,将其除以2得到它的父结点B的存储单元下标,而将其乘以2则是它的左孩子w存储单元的下标,当然将其乘2再加1则是它右孩子K的存储单元下标。
在这里插入图片描述
在这里插入图片描述

链式存储

虽然顺序存储的空间利用率高,计算简单,但是其不适于一般的二叉树
如图为给定的二叉树。给出了从上至下、从左至右的层序存储的对应结点编号,其中灰色结点是为了满足顺序存储要求而增加的“虚”结点,可以在相应的存储单元存放一个特殊的数值,以区别于其他“实结点”。图4.10(c)则是最终的存储结果。
可以看到,5个结点的二叉树,顺序存储需要13个存储单元,超过一半的存储空间浪费掉了。更有甚者,对一个深度为h的右斜二叉树来讲,需要2-1个存储单元,而实际上该斜二叉树只有k个结点。

另外,二叉树的顺序存储方式避免不了顺序存储的固有缺点,即不易实现增加、删除操作。因此,二叉树的顺序存储方式适用于一定的条件,对于不需要修改的完全二叉树,是一种较好的选择。
实际上,二叉树的最常用表示方法是用链表表示,每个结点由数据和左右指针三个数据成员组成。

结构定义

typedef int ElementType;
typedef struct TNode* Position;
typedef Position BinTree;
struct TNode {ElementType Data;//结点数据BinTree Left; //指向左子树BinTree Right; //指向右子树
};

操作实现

遍历

我们用L,V,R分别表示遍历左分支L,访问结点V,遍历右分支R,那么可以有以下6种情况:LVR,LRV,VLR,VRL,RLV,RVL。
规定:访问左分支在右分支之前,只剩下:LVR, LRV, VLR。
我们按照V的位置分别将其命名为:中序遍历,后序遍历,先序遍历

中序遍历

对树的任一结点的访问是在先遍历完其左子树后进行的,访问此结点后,在对其右子树遍历
遇到每个结点,其遍历过程

  1. 中序遍历左子树
  2. 访问根节点
  3. 中序遍历右节点
void InorderTraveral(BinTree BT) {if (BT) {InorderTraveral(BT->Left);printf("%d\n, BT->Data");InorderTraveral(BT->Right);}
}
后序遍历

对结点的左右子树先进行遍历,然后才对此结点访问。遍历是从根节点开始,遇到每个结点时,其遍历过程是:

  1. 后序遍历其左子树
  2. 后序遍历其右子树
  3. 访问根节点
void PostorderTraversal(BinTree BT) {if (BT) {PostorderTraversal(BT->Left);printf("%d\n, BT->Data");PostorderTraversal(BT->Right);}
}
先序遍历

对结点的访问是在其左、右子树遍历之前进行的。遍历是从根节点开始,遇到每个结点时,其遍历过程是:

  1. 访问根结点
  2. 先序遍历其左子树
  3. 先序遍历其右子树
void PreorderTraversal(BinTree BT) {if (BT) {printf("%d\n, BT->Data");PreorderTraversal(BT->Left);PreorderTraversal(BT->Right);}
}
非递归遍历

在沿左子树深入时,进入一个结点就将其压入堆栈。
若是先序遍历,则在入栈之前访问之;当沿左分支深入不下去时,则返回,即从堆栈中弹出前面压入的结点;
若为中序遍历,则此时访同该结点,然后从该结点的右子树继续深入;
若为后序遍历,则将此结点二次入栈,然后从该结点的右子树继续深入,与前面类同,仍为进入一个结点入栈一个结点,深入不下去再返回,直到第二次从栈里弹出该结点,才访问之。

对于非递归中序遍历,遇到一个节点就将其压栈,并去遍历其左子树;当左子树结束后,从栈顶弹出结点并访问它,然后按其右指针再去中序遍历该节点的右子树。

void InorderTraversalUn(BinTree BT) {BinTree T;Stack S = CreateStack(100);T = BT;while (T || !IsEmpty(S)) {while (T) {Push(S, T);T = T->Left;}T = Pop(S);printf("%d\n, T->Data");T = T->Right;}}
层序遍历

层序遍历是按照树的层次,从第一层的根结点开始向下逐层访问每个结点,对每一层的结点按照从左到右的顺序访问。
可以设置一个队列结构,遍历从根节点开始,首先将根节指针入队,然后执行以下操作:

  1. 从队列取出一个元素
  2. 访问该元素所指向的结点
  3. 若元素所指向的结点的左右孩子非空,将其左、右孩子的指针入队。
    不断执行这三步,直到队列为空。
void LevelorderTraversal(BinTree BT) {Queue Q;BinTree T;T = BT;Q = CreateQueue(100);AddQ(Q, T);while (!IsEmptyQ(Q)) {T = DeleteQ(Q);printf("%d\n, T->Data");if (!T->Left) { AddQ(Q, T->Left); }if (!T->Right) { AddQ(Q, T->Right); }}
}

相关文章:

【数据结构】16 二叉树的定义,性质,存储结构(以及先序、后序、中序遍历)

二叉树 一个二叉树是一个有穷的结点集合。 它是由根节点和称为其左子树和右子树的两个不相交的二叉树组成的。 二叉树可具有以下5种形态。 性质 一个二叉树第i层的最大结点数为 2 i − 1 2^{i-1} 2i−1, i ≥ 1 i \geq 1 i≥1 每层最大结点可以对应完美二叉树(…...

GPT SOVITS项目 一分钟克隆 (文字输出)

步骤流程:(首先使用UVR 提取人声文件,然后按下面步骤进行) 注意这里提交的音频是参考的音频...

python34-Python列表和元组之加法

列表和元组支持加法运算,加法的和就是两个列表或元组所包含的元素的总和。 需要指出的是,列表只能和列表相加;元组只能和元组相加;元组不能直接和列表相加。 如下代码示范了元组和列表的加法运算。 # !/usr/bin/env python# -*- coding: utf-8 -*-# T…...

不做程序员了(转岗半年后对程序员岗位的思考)

不做程序员了(转岗半年后对程序员岗位的思考) 前言 好久没有更新了,已经久到CSDN的小编来问我为什么不更了。原因是我半年前转岗了,不再做程序员了,由程序员变为了产品经理。废话不多说,换个视角来给大家…...

DS:八大排序之直接插入排序、希尔排序和选择排序

创作不易,感谢三连支持!! 一、排序的概念及运用 1.1 排序的概念 排序:所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起 来的操作。稳定性&…...

【MySQL】-21 MySQL综合-8(MySQL默认值+MySQL非空约束+MySQL查看表中的约束)

MySQL默认值MySQL非空约束MySQL查看表中的约束 MySQL默认值在创建表时设置默认值约束在修改表MySQL默认值在创建表时设置默认值约束在修改表时添加默认值约束删除默认值约束删除默认值约束 MySQL非空约束在创建表时设置非空约束在修改表时添加非空约束删除非空约束 MySQL查看表…...

力扣hot3--并查集+哈希

第一想法是排个序然后遍历一遍,but时间复杂度就超啦 并查集居然与哈希结合了() 已经好久没用过并查集了,,,我们用哈希表f_node中来记录原结点的父节点,其中key是原结点,value是父节点…...

微信网页版能够使用(会顶掉微信app的登陆)

一、文件结构 新建目录chrome新建icons,其中图片你自己找吧新建文件manifest.json新建文件wx-rules.json 二、文件内容 对应的png你们自己改下 1、manifest.json {"manifest_version": 3,"name": "wechat-need-web","author…...

word软件中硬件图像加速有什么用处?禁用硬件图形加速(G)会影响word文档中插入图片的分辨率吗?

问题描述:word软件中硬件图像加速有什么用处?禁用硬件图形加速(G)会影响word文档中插入图片的分辨率吗? 问题解答: 在 Microsoft Word 中,硬件图形加速主要用于提高图形元素的渲染速度和性能,特别是处理大…...

.NET Core MongoDB数据仓储和工作单元模式封装

前言 上一章我们把系统所需要的MongoDB集合设计好了,这一章我们的主要任务是使用.NET Core应用程序连接MongoDB并且封装MongoDB数据仓储和工作单元模式,因为本章内容涵盖的有点多关于仓储和工作单元的使用就放到下一章节中讲解了。仓储模式(R…...

lua:有关表访问的metamethod

针对在两种正常状态:表的不存在的域的查询和修改,Lua也提供了改变 tables的行为的方法。 index metamethod 我们可以通过index元方法来实现访问table内部不存在的域时人为操控返回数据。 比如以下测试代码: local set {1,2,3} setmetata…...

【MySQL】索引事务

MySQL索引事务 1. 索引1.1 概念1.2 作用1.3 使用场景1.4 使用1.5 案例 2. 事务2.2 事物的概念2.3 使用 3. 内容重点总结 1. 索引 1.1 概念 索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引, 并指定索引的类…...

ChatGPT重大升级:能自动记住用户的习惯和喜好,用户有权决定是否共享数据给OpenAI

OpenAI刚刚宣布了ChatGPT的一项激动人心的更新! OpenAI在ChatGPT中新加了记忆功能和用户控制选项,这意味着GPT能够在与用户的互动中记住之前的对话内容,并利用这些信息在后续的交谈中提供更加相关和定制化的回答。 这一功能目前正处于测试阶…...

CSS设置盒子阴影

语法 box-shadow: *h-shadow v-shadow blur spread color* inset; 注释: box-shadow向框添加一个或多个阴影. 该属性是由逗号分隔的阴影列表,每个阴影由2-4个长度值、可选的颜色值及可选的inset关键词来规定。省略长度的值是0。 外阴影 a、给元素右边框和下边框加外阴影——把…...

文件夹删不掉,显示在另一个文件中打开怎么办

问题: 一、想要删掉这个文件夹,却因为文件夹中的文件打开了删不掉,这里我因为做的测试,所以是知道打开了什么 二、一般情况下文件比较多时,是不知道打开了什么的,长这个样子 解决: 一、打开任…...

阿里云香港云服务器租用_BGP多线网络_CN2高速线路测试

阿里云香港服务器中国香港数据中心网络线路类型BGP多线精品,中国电信CN2高速网络高质量、大规格BGP带宽,运营商精品公网直连中国内地,时延更低,优化海外回中国内地流量的公网线路,可以提高国际业务访问质量。阿里云服务…...

C# 异步方法的使用场景

我一直认为C#的异步方法只是一堆华而不实的东西,坑特别多,比起直接自建线程也没有任何优势。 直到有一天,一个需求场景,让我再次想到了C#的异步方法。 需求场景如下:需要写一个程序控制机械臂完成各种动作。每个动作要…...

Lua 教程

Lua 教程 (今天又又又开新坑啦) Lua 教程 手册简介 Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放。 手册说明 Lua是什么? Lua 是一个小巧的脚本语言。是巴西里约热内卢天主教大学(Pontifical Catholic University of Rio de …...

CleanMyMac X2024版本有哪些常见的使用场景?

CleanMyMac X作为一款Mac电脑清理和优化工具,具有多种使用场景。以下是一些常见的使用场景: 清理系统垃圾文件:CleanMyMac X可以智能扫描Mac磁盘空间,清理系统冗余文件和各种软件应用产生的垃圾文件,如缓存、日志文件…...

《Docker快速入门:从0到1构建你的第一个容器!》

《Docker快速入门:从0到1构建你的第一个容器!》 前言 欢迎来到Docker的世界,一个让应用程序打包、部署和运行更加容易的神奇平台。Docker改变了我们对于应用开发和分发的看法,它通过容器技术让软件的携带和运行变得前所未有的轻…...

Docker 离线安装指南

参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...

深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用

文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...

AirSim/Cosys-AirSim 游戏开发(四)外部固定位置监控相机

这个博客介绍了如何通过 settings.json 文件添加一个无人机外的 固定位置监控相机,因为在使用过程中发现 Airsim 对外部监控相机的描述模糊,而 Cosys-Airsim 在官方文档中没有提供外部监控相机设置,最后在源码示例中找到了,所以感…...

力扣热题100 k个一组反转链表题解

题目: 代码: func reverseKGroup(head *ListNode, k int) *ListNode {cur : headfor i : 0; i < k; i {if cur nil {return head}cur cur.Next}newHead : reverse(head, cur)head.Next reverseKGroup(cur, k)return newHead }func reverse(start, end *ListNode) *ListN…...

为什么要创建 Vue 实例

核心原因:Vue 需要一个「控制中心」来驱动整个应用 你可以把 Vue 实例想象成你应用的**「大脑」或「引擎」。它负责协调模板、数据、逻辑和行为,将它们变成一个活的、可交互的应用**。没有这个实例,你的代码只是一堆静态的 HTML、JavaScript 变量和函数,无法「活」起来。 …...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

恶补电源:1.电桥

一、元器件的选择 搜索并选择电桥&#xff0c;再multisim中选择FWB&#xff0c;就有各种型号的电桥: 电桥是用来干嘛的呢&#xff1f; 它是一个由四个二极管搭成的“桥梁”形状的电路&#xff0c;用来把交流电&#xff08;AC&#xff09;变成直流电&#xff08;DC&#xff09;。…...

《信号与系统》第 6 章 信号与系统的时域和频域特性

目录 6.0 引言 6.1 傅里叶变换的模和相位表示 6.2 线性时不变系统频率响应的模和相位表示 6.2.1 线性与非线性相位 6.2.2 群时延 6.2.3 对数模和相位图 6.3 理想频率选择性滤波器的时域特性 6.4 非理想滤波器的时域和频域特性讨论 6.5 一阶与二阶连续时间系统 6.5.1 …...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...

LangChain【6】之输出解析器:结构化LLM响应的关键工具

文章目录 一 LangChain输出解析器概述1.1 什么是输出解析器&#xff1f;1.2 主要功能与工作原理1.3 常用解析器类型 二 主要输出解析器类型2.1 Pydantic/Json输出解析器2.2 结构化输出解析器2.3 列表解析器2.4 日期解析器2.5 Json输出解析器2.6 xml输出解析器 三 高级使用技巧3…...