数据结构与算法-树

news2024/11/19 1:53:20

  • 🎈1.树和二叉树
  • 🎈2.树
    • 🔭2.1树的定义
    • 🔭2.2树的4种表示方法
    • 🔭2.3树的基本术语
    • 🔭2.4树的抽象数据类型定义
  • 🎈3.二叉树
    • 🔭3.1二叉树的定义
    • 🔭3.2二叉树的抽象数据类型定义
    • 🔭3.3满二叉树
    • 🔭3.4完全二叉树
    • 🔭3.5完全二叉树的特点
    • 🔭3.6二叉树的性质
    • 🔭3.7二叉树的存储结构
    • 🔭3.8完全二叉树的顺序存储
    • 🔭3.9一般二叉树的存储结构
    • 🔭3.10二叉树的链式存储结构
  • 🎈4.二叉树的类定义及其实现
    • 🔭4.1二叉树的类定义
    • 🔭4.2二叉树的实现
      • 📖4.2.1创建二叉树
      • 📖4.2.2计算二叉树的高度
      • 📖4.2.3计算二叉树的树叶数
      • 📖4.2.4查找二叉树

🎈1.树和二叉树

树结构是一类重要的非线性结构,树型结构是结点之间有分支,并且具有明显的层次关系的结构,它类似于自然界中的树。树结构在客观世界是大量存在的,例如行政组织机构和人类社会的家谱都可以用树来形象表示。

🎈2.树

🔭2.1树的定义

树是n(n>=0)个结点的有限集T
n=0,称为空树。
n>0,则它满足以下两个条件:
(1).有且仅有一个特定的称为根的结点。
(2).其余结点可以分为m(m>=0)个互不相交的有限集T1,T2,T3......Tm,其中,每个集合本身又是一棵树,并称为根的子树。

🔭2.2树的4种表示方法

在这里插入图片描述

🔭2.3树的基本术语

在这里插入图片描述


  • 结点:树中每个元素对应一个结点。每个结点包含一个数据元素及若干指向子树的分支。例如,图中的树有11个结点,结点D包含3个分支。
  • 结点的度:结点所拥有的子树的个数称为结点的度。例如,结点A和D的度均为3,结点B的度为2,结点C的度为1,结点F的度为0。
  • 叶子结点:度为0的结点称为叶子结点(或称树叶),又称终端结点。例如,上图所示,E,F,G,H,I,K都是叶子结点。
  • 分支结点:度不为0的结点称为分支结点,又称非终端结点。例如,上图所示的树,A,B,C,D,J都是分支结点。
  • 树的度:树中所有结点的最大度数称为树的度。例如,图所示的树的度为3.
  • 双亲结点:若结点X有孩子,则X为孩子的双亲结点,简称双亲。例如,在图所示的树中,结点H,I,J的双亲是D,根结点A没有双亲,树中只有根结点没有双亲
  • 孩子结点:若结点X由子树,则子树的根结点即为结点X的孩子结点,简称孩子。例如,结点D有三个孩子H,I,J。
  • 兄弟结点:同一双亲的孩子结点称为兄弟结点,简称兄弟。例如,结点H,I,J为兄弟。
  • 堂兄弟结点:在树中的层次相同,但双亲不同的结点称为堂兄弟,简称堂兄。例如,结点F,G,H为堂兄弟。
  • 祖先结点:从根结点到结点X所经过分支上的所有结点,都称为X的祖先结点,简称祖先。例如,K的祖先为A,D,J
  • 子孙结点:结点X的孩子,以及这些孩子的孩子都是X的子孙结点。例如,结点D的子孙为H,I,J,K
  • 结点的层次:根结点的层次为1,根结点的孩子的层次为2,根结点的孩子的孩子的层次为3,依次类推。
  • 树的深度:树中结点的最大层次称为树的深度,也称树高。空树的深度为0,只有一个根结点的树的深度为1,图所示的树的深度为4.
  • 路径:从树的某个结点X到其子孙结点Y所经过的路线叫做路径,路径上经过的边的数称为路径长度。由于树中无回路,所以树的路径是唯一的。如图所示的树中,从A到结点K的路径是A,D,J,K,路径长度为3.
  • 森林:m(m>=)棵互不相交的树构成的集合称之为森林。

🔭2.4树的抽象数据类型定义

ADT Tree{
数据对象D:D为性质相同的数据元素的集合
数据关系R:
若D为空集,则称为空树。
若D仅有一个数据元素,则R=空集,否则R!=空集。
(1.在D中存在唯一的称为根的数据元素root,它在关系R下无前驱。
(2.存在D-{root}的一个划分{D1,D2,...,Dm}(m>0,且对于(1<=i<=m),存在唯一的数据元素Xi属于Di,(root,Xi)属于R.3.对应于D-{root}的一个划分,r-{(root,x1),(root,x2),...,(root,Xm)}存在唯一的一个划分{R1,R2,...,Rm}(m>0),对于(1<=i<=m),Ri是Di上的二元关系,(xi,Ri)(i=1,2,...,m)是一棵符合本定义的树,称为根root的子树。

基本操作:
InitTree(&t):构造一棵空树
DestroyTree(&t):销毁一棵树
Parent(t,e):求结点e的双亲结点
Sons(t,e):求结点e有所有孩子结点
LeftChild(t,e):返回结点e的右兄弟最左孩子
RightSibling(t,e):返回结点e的右兄弟结点
TraraverseTree(t,visit()):visit()函数访问树中每个结点
DepthTree(t):返回树的深度
}ADT Tree

🎈3.二叉树

🔭3.1二叉树的定义

二叉树是由n(n>=0)个结点构成的有限集合,该集合或者为空集,此时称为空二叉树,或由一个根结点及两棵互不相交的左右子树组成,并且左右子树均是二叉树。二叉树的子树有左右之分,其次序不能颠倒。

二叉树的定义也是一个递归定义,二叉树可以是空集合,根可以有空的左子树或空的右子树。。二叉树不是树的特殊情况,它们是两个概念。二叉树中即使只有一棵子树也要进行区分,说明它是左子树,还是右子树,这是二叉树与树的最主要的差别。“二叉树是结点度为2的树”的说法是错误的。二叉树的5种基本形态:
在这里插入图片描述

🔭3.2二叉树的抽象数据类型定义

在这里插入图片描述

🔭3.3满二叉树

一棵深度为k且有2k-1个结点的二叉树称为满二叉树。满二叉树的特点是每一层上结点数都是最大结点数。如图所示,是一棵深度为4的满二叉树。
在这里插入图片描述

🔭3.4完全二叉树

可以对满二叉树的结点进行顺序编号,约定编号从根结点开始,自上而下,从左至右(称为层序编号)。
如果一棵深度为k且具有n个结点的二叉树,它的每个结点都与深度为k的满二叉树中的顺序编号1~n的结点一一对应,则称这棵二叉树为完全二叉树。
在这里插入图片描述

🔭3.5完全二叉树的特点

  1. 叶子结点只能在第k层和第k-1层上出现。
  2. 对于任意结点,若其右子树的深度为l,则其左子树的深度为ll+1
  3. 度为1的结点数为0或1。当结点的总数为奇数时,度为1的结点数为0,当结点的总数为偶数时,度为1的结点数为1.

🔭3.6二叉树的性质

  1. 二叉树的第i层上至多有2i-1(i>=1)个结点。
  2. 深度为k的二叉树最多有2k-1(k>=1)个结点。
  3. 对于任何一棵二叉树,如果其叶子结点数为n0,度为2的结点数为n2,则n0=n2+1.
    性质3推论:对于任何一棵k叉树,如果叶子结点数为n0,度为1,2,...k的结点数分别为n1,n2,...,nk,则n0=n2+2n3+3n4+...(k-1)nk+1.

例:一棵三叉树中,已知度为3的结点数等于度为2的结点数,且叶子结点数为10,则度为3的结点为多少?
n0 = n2+2n3+1=3n3+1
n3 = 3


  1. 一棵具有n个结点的完全二叉树的深度为[log2n]+1(以2为底,n的对数)。
  2. 在这里插入图片描述

🔭3.7二叉树的存储结构

二叉树的顺序存储结构是用一组地址连续的存储单元来存放二叉树的数据元素。

📝二叉树的顺序存储结构类型定义如下:

#define MaxSize 100  //二叉树的最大存储容量
typedef ElemType SqBiTree[MaxSize]  //用数组存储二叉树的数据元素
SqBiTree bt;

🔭3.8完全二叉树的顺序存储

在用数组存储二叉树时,必须确定树中各数据元素的存放次序,使各数据元素的相应位置反映出数据元素之间的逻辑关系用一组地址连续的存储单元依次自上而下、自左而右地存储完全二叉树的结点元素。
在这里插入图片描述

🔭3.9一般二叉树的存储结构

在采用顺序存储时,应采用完全二叉树的编号方式,没有编号的结点在对应的位置上用#表示。
在这里插入图片描述
:对于完全二叉树而言,采用顺序存储结构方式是十分合理的,它能够充分利用存储空间,但对于一般的二叉树而言,这种存储方式必然会造成大量空间浪费。在最坏的情况下,一棵深度为k且只有k个单分支二叉树,却需要长度为2k-1的一维数组来存储。因此,一般二叉树常采用链式存储方式

🔭3.10二叉树的链式存储结构

根据二叉树的定义,二叉树的每个结点可以有两个分支,分别指向及诶单的左子树和右子树。在二叉树中,标准存储方式的结点结构如图所示:
在这里插入图片描述
其中,data表示数据域,用来存放数据元素信息。
lchild表示左指针域,用来存放指向左孩子的指针,当左孩子不存在时为空指针。
rchild表示右指针域,用来存放指向右孩子的指针,当右孩子不存在时为空指针。
这种链式存储结构通常称为二叉链表。

二叉链表的结点类型定义:
typedef struct BitNode
{
     ElemType data;//数据元素信息
     BitNode *lchild;//指向左孩子结点
     BitNode *rchild;//指向右孩子结点
}BitNode;

由二叉树的链式存储结构可知,对于具有n个结点的二叉树,每个结点有两个指针域,共有2n个指针域,其中n-1个非空链域,n+1个空链域。

🎈4.二叉树的类定义及其实现

🔭4.1二叉树的类定义

#include <iostream>
using namespace std;
typedef struct BitNode
{
	char data;
	BitNode* lchild;
	BitNode* rchild;
}BitNode;
class BiTree
{
private:
	BitNode* bt;
	void Rcreate(BitNode*& t);//递归创建二叉树
	void PreTraverse(BitNode* t);//先序遍历递归函数
	void InTraverse(BitNode* t);//中序遍历递归函数
	void PostTraverse(BitNode* t);//后序遍历递归函数
	int BTNodeDepth(BitNode* t);//计算二叉树的树高递归函数
	int BTNodeLeaf(BitNode* t);//计算二叉树树叶数递归函数
	BitNode* SearchNode(BitNode* t, char x);//查找值等于x的结点递归函数
public:
	BiTree()
	{
		bt = NULL;//创建空树
	}
	void RcreateBiTree();//创建二叉树
	void PreTraverseBiTree();//先序遍历二叉树
	void InTraverse();//中序遍历二叉树
	void PostTraverse();//后序遍历二叉树
	int BTNodeDepthBiTree();//计算二叉树的树高
	int BTNodeLeafBiTree();//计算二叉树的叶子数
	BitNode* SearchNodeBit(char x);//查找值等于x的结点
};

🔭4.2二叉树的实现

📖4.2.1创建二叉树

Rcreate()函数递归创建二叉树,其过程为:读入字符ch,若ch=='.',则创建空二叉树,若ch!='.',则先创建左子树,再创建右子树。

void BiTree::Rcreate(BitNode*& t)
{
	char ch;
	cin >> ch;
	if (ch == '.')
		t = NULL;
	else
	{
		t = new BitNode;//申请空间
		t->data = ch;
		Rcreate(t->lchild);//递归创建左子树
		Rcreate(t->rchild);//递归创建右子树
	}
}
void BiTree::RcreateBiTree()
{
	BitNode* t;
	Rcreate(t);//递归创建二叉树
	bt = t;//将根结点指针赋值给私有成员bt
}

📖4.2.2计算二叉树的高度

BTNodeDepth()函数递归计算二叉树的树高,其过程为:判断二叉树t是否为空树,若为空树,树高则为0。若为非空树,则计算左子树的高度m和右子树的高度n;m>=n,返回m,否则返回n.

在这里插入图片描述

int BiTree::BTNodeDepth(BitNode* t)
{
	if (t == NULL)
		return 0;
	else
	{
		int m = 1 + BTNodeDepth(t->lchild);//计算左子树树高度
		int n = 1 + BTNodeDepth(t->rchild);//计算右子树树高度
		if (m >= n)//比较左右子树高度
			return m;
		else
			return n;
	}
}
int BiTree::BTNodeDepthBiTree()
{
	//计算二叉树的高度
	BitNode* p = bt;
	return BTNodeDepth(p);//调用计算二叉树高度的递归函数
}

📖4.2.3计算二叉树的树叶数

BTNodeLeaf()计算二叉树的树叶数,其过程为:判断t是否为空树,若为空树,则树叶数为0;若为非空树,则计算左子树的树叶数m和右子树的树叶数nm+n=0时返回1m+n!=0时返回m+n.
在这里插入图片描述

int BiTree::BTNodeLeaf(BitNode* t)
{
	//递归算法计算二叉树的树叶数
	if (t == NULL)
		return 0;
	else
	{
		int m = BTNodeLeaf(t->lchild);
		//计算左子树的树叶数
		int n = BTNodeLeaf(t->rchild);
		//计算右子树的树叶数
		if (m + n == 0)
			return 1;
		else
			return m + n;
	}
}
int BiTree::BTNodeLeafBiTree()
{
	//计算二叉树的树叶数
	BitNode* p = bt;//读取私有成员指针bt
	return BTNodeLeaf(p);//调用二叉树的树叶数的递归函数
}

📖4.2.4查找二叉树

SearchNode()函数在二叉树t中查找值等于x的结点,若找到该结点时返回其首地址,否则返回NULL.判断t是否为空树,若为空树,则返回NULL,若为非空树,则在t->data==x时返回t,在t->data!=x时,在左子树中查找,否则在右子树中查找。
在这里插入图片描述

BitNode* BiTree::SearchNode(BitNode* t, char x)
{
	BitNode* p;
	if (t == NULL)
		return NULL;
	if (t->data == x)
		return t;
	else
	{
		p = SearchNode(t->lchild,x);//递归查找左子树
		if (p != NULL)
			return p;
		else
			return SearchNode(t->rchild, x);//递归查找右子树
	}
}
BitNode* BiTree::SearchNodeBit(char x)
{
	BitNode* p = bt;
	return SearchNode(p, x);
}

好啦,关于二叉树的知识到这里并没有结束,后期会继续更新二叉树的相关知识,欢迎大家持续关注、点赞和评论!❤️❤️❤️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1117248.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySQL 性能分析

MySQL 性能分析 对 mysql 进行性能分析&#xff0c;主要就是提升查询的效率&#xff0c;其中索引占主导地位。对 mysql 进行性能分析主要有如下几种方式&#xff1a; 方式一&#xff1a;查看 sql 执行频次 show global status like ‘Com_______’; // global 表示全局 show s…

力扣每日一题49:字母异位词分组

题目描述&#xff1a; 给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。 示例 1: 输入: strs ["eat", "tea", "tan", "ate&quo…

国产低功耗MCU芯片:Si24R03

Si24R03集成了基于RISC-V核的低功耗MCU和工作在2.4GHz ISM频段的无线收发器模块&#xff0c;是一款高度集成的低功耗SOC片。 应用领域&#xff1a; 1、物联网 2、智N门锁 3、电机控制 4、消费电子 5、工业控制 其无线收发器模块是专为低功耗无线场合设计&#xff0c;在关…

微信小程序开发的OA会议之会议,投票,个人中心的页面搭建及模板

目录 一.自定义组件 1.1.创建 1.2.定义 1.3.编写 1.4.使用 二.会议 2.1.数据 2.2.显示 2.3. 样式 三.个人中心 3.1.页面 3.2.样式 四.投票 4.1.引用 4.2.数据 4.3.页面 4.4.样式 好啦今天就到这里了&#xff0c;希望能帮到你哦&#xff01;&#xff01;&…

UGUI交互组件Dropdown

一.Dropdown的应用 Dropdown控件官方翻译为下拉选单&#xff0c;游戏中有一定程度的使用&#xff0c;其优势是用户体验优秀&#xff0c;节省界面空间&#xff0c;下图为某游戏的实际应用 二.Dropdown对象的结构 对象说明Label当前选中的选项Arrow向下或向上箭头表示展开方向Te…

Ubuntu服务器配置qq邮箱发送信息

效果&#xff1a; 此处设置的是自己给自己发送&#xff0c;配合linux的cron实现定时触发发送事件的效果 实现过程&#xff1a; 安装邮箱客户端Postfix sudo apt-get install postfix配置Postfix&#xff1a;编辑Postfix的主要配置文件 /etc/postfix/main.cf&#xff0c;并在…

uni-app:js实现数组中的相关处理

一、查询数组中&#xff0c;某一项中的某个数据为指定值的项&#xff08;find() 方法&#xff09; 使用分析 使用数组的 find() 方法来查询 id 为 0 的那一项数据。这个方法会返回满足条件的第一个元素&#xff0c;如果找不到符合条件的元素&#xff0c;则返回 undefined。使用…

跨路由器路由设置

1781的eth0网口地址设置为192.168.3.45并接入192.168.3.0网段里&#xff1b; 1781的eth1网口地址设置为10.0.9.20并接入10.0.0.0网段里&#xff0c;并且连接在网关地址为10.0.9.1的路由上。 192.168.1.140的摄像头接在网关为10.0.9.1的路由器上 现在的需求是1781网关在访问19…

CardView设置任意角为圆角

注意&#xff1a;material:1.1.0以上版本在RadiusCardView节点下一定要添加 android:theme“style/Theme.MaterialComponents”&#xff0c;不然会报错&#xff0c;另外&#xff0c;由于是重写自MaterialCardView&#xff0c;所以一定要导入material包&#xff1a; implementat…

2022年京东双11食品饮料品类数据回顾

2022年双11&#xff0c;根据京东官方发布的数据显示&#xff0c;京东百货中&#xff0c;京东新百货的589个品类10025个品牌成交额同比增长100%。而在食品饮料行业中&#xff0c;也有一些在大促期间成交额同比涨幅超过100%的品牌。 下面&#xff0c;结合鲸参谋平台提供的数据&am…

达梦mysql数据迁移出现datetime兼容问题

迁移工具无法连接mysql 这里需要指定驱动即可 数据迁移datetime数据无法导入 原因是时间中间带有T&#xff0c;达梦不支持这个格式的时间 解决办法也很简单&#xff0c;换最新的达梦驱动。 驱动安装文件里边就有&#xff0c;不用再去下载了。

【lesson13】进程地址空间收尾

文章目录 进程地址空间存在的原因原因一原因二原因三 重新理解什么是挂起&#xff1f; 进程地址空间存在的原因 原因一 凡是非法访问或者映射&#xff0c;OS都会识别到&#xff0c;并终止该进程。 例子&#xff1a; 我们会发现我们定义的字符串常量只有只读权限&#xff0c;…

Hadoop3教程(三十):(生产调优篇)纠删码

文章目录 &#xff08;155&#xff09;纠删码原理纠删码原理纠删码相关命令纠删码策略解释 &#xff08;156&#xff09;纠删码案例实操参考文献 &#xff08;155&#xff09;纠删码原理 纠删码原理 默认情况下&#xff0c;一个文件在HDFS里会保留3个副本&#xff0c;以此提高…

2023年【北京市安全员-A证】考试报名及北京市安全员-A证考试资料

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 北京市安全员-A证考试报名根据新北京市安全员-A证考试大纲要求&#xff0c;安全生产模拟考试一点通将北京市安全员-A证模拟考试试题进行汇编&#xff0c;组成一套北京市安全员-A证全真模拟考试试题&#xff0c;学员可…

【大揭秘】美团面试题:ConcurrentHashMap和Hashtable有什么区别?一文解析!

正文 亲爱的小伙伴们&#xff0c;大家好&#xff01;我是小米&#xff0c;一个热爱技术分享的程序员&#xff0c;今天我为大家带来了一篇有关美团面试题的热门话题&#xff1a;ConcurrentHashMap 和 Hashtable 有什么区别。这个问题在Java面试中常常被拿来考察对多线程编程的理…

基于TCP的RPC服务

TCP服务器上的RPC&#xff0c;通过创建一个服务器进程监听传入的tcp连接&#xff0c;并允许用户 通过此TCP流执行RPC命令 -module(tr_server). -author("chen"). -behaviour(gen_server).%% API -export([start_link/1,start_link/0,get_count/0,stop/0 ]).-export(…

基于金豺优化的BP神经网络(分类应用) - 附代码

基于金豺优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码 文章目录 基于金豺优化的BP神经网络&#xff08;分类应用&#xff09; - 附代码1.鸢尾花iris数据介绍2.数据集整理3.金豺优化BP神经网络3.1 BP神经网络参数设置3.2 金豺算法应用 4.测试结果&#xff1a;5.M…

TUI界面容器管理工具Oxker

什么是 Oxker &#xff1f; Oxker 是一个基于文本的用户界面&#xff0c;用于查看 Docker 容器的信息和统计数据。一目了然&#xff0c;Oxker 提供了容器列表、其当前状态、对系统资源&#xff08;CPU、内存&#xff09;的影响、容器 ID、镜像名称、大小等。该应用程序还提供用…

虚拟机weblogic服务搭建及访问(物理机 )

第一、安装环境&#xff1a; weblogic10.3.6.jar, jdk1.6.bin(开始安装jdk1.8后&#xff0c;安装域的时候报错 &#xff0c;版本很重要&#xff09; centos7虚拟机&#xff08;VMware9&#xff09; 本机系统windows7 以上安装包如果需要可以私信我&#xff0c;上传资源提示…

2023年【汽车驾驶员(高级)】考试试卷及汽车驾驶员(高级)理论考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 汽车驾驶员&#xff08;高级&#xff09;考试试卷根据新汽车驾驶员&#xff08;高级&#xff09;考试大纲要求&#xff0c;安全生产模拟考试一点通将汽车驾驶员&#xff08;高级&#xff09;模拟考试试题进行汇编&…