树的基本概念及二叉树

news2024/9/28 23:33:39

目录

一、树的基本概念

(1)树的结点

(2)度

(3)结点层次

(4)树的高度 

树的特点: 

二、二叉树

(1)满二叉树

(2)完全二叉树 

三、二叉树的存储 

(1)顺序存储

(2)链式存储 

四、二叉树的遍历

(1)前序遍历

(2)中序遍历 

 (3)后序遍历

 (4)层序遍历


树是一种非线性的数据结构,存储具有“一对多”关系特点元素的一种数据结构。例如:组织架构、图书目录、商品种类、热点搜索词等。

如图所示就是一个 树 ,对数据A来说,和数据C、F有关系;对于数据F来说,和数据H、G有关系。这就是“一对多”的关系。 

将具有“一对多”关系的集合中的数据元素按照树的形式进行存储,整个存储形状在逻辑结构上看,类似于实际生活中倒着的树,所以称这种数据的存储结构称为“树”。

一、树的基本概念

树是一种非线性的数据结构,包含n个结点的有限集合,结点之间具备一对多的逻辑关系,当树的结点n=0时,该树被称为空树。

(1)树的结点

树结构中,存储的每一个数据元素都被称为树的“结点”。

结点又被细分为:根节点、子节点、叶子结点

 如图所示:叶子结点即树的末端结点,属于没有子结点的结点,统一称为叶子结点。

子树:由某个子结点作为根结点组成的树被称为子树。上图中红色部分就是一个子树。

(2)度

对于一个结点,拥有的子树个数(结点有多少分支)称为结点的度

树的度:一颗树的度是树内各结点的度的最大值。

(3)结点层次

从一棵树的根结点开始,根结点所在层为第一层,根结点的子结点所在层为第二层,依次类推

(4)树的高度 

一棵树的高度是树中结点所在的最大层次。树的高度,也被称为树的深度。

树的特点: 

在任意一个非空树中,有以下特点:

1.有且仅有一个根结点

2.一棵树中的任意两个结点,有且仅有唯一的一条路径连通,不存在回路。

3.一棵树如果有n个结点,那么它一定有n-1条边

二、二叉树

二叉树是一种结点的度不大于2的有序树,子结点通常被称为“左孩子结点”和“右孩子结点”。

 如图所示就是一个二叉树

 这个图中树的度为3,所以此树就不是一个二叉树

二叉树又被分为满二叉树完全二叉树 

(1)满二叉树

满二叉树是一种特殊的二叉树,它的所有非叶子节点都存在左右子结点,并且所有的叶子结点都在同一层级

image.png

满二叉树的特点:

(2)完全二叉树 

如果二叉树中,从根结点到倒数第二层,符合满二叉树要求,其叶子结点可以不完全填充,但必须靠从左到右连续分布,这样的二叉树被称为完全二叉树。

image.png

三、二叉树的存储 

(1)顺序存储

顺序存储指的是使用顺序表(数组)存储二叉树。但是顺序存储只适用于完全二叉树。满二叉树也是完全二叉树,所以同样适用。

在顺序存储中,顺序表中的每一个位置仅存储结点的data,不需要存储左右子结点的指针,子结点的索引通过计算父结点下标完成。

如果一个父结点的下标为parentIndex它的左结点下标为:2parentIndex,  右子结点下标为:2parentIndex+1

如果完全二叉树,使用数组顺序存储,可以完全利用数组空间

完全二叉树的顺序存储.png

如果是普通二叉树,使用数组顺序存储,在数组中就会出现空隙,导致内存利用率降低

二叉树的顺序存储.png

//基于数组(顺序存储)的二叉树
public class BinaryTree1<E> {
//	创建一个新的空数组用来存储二叉树
	private Object[] elementData=null;
//	进行初始化操作
	public BinaryTree1(E[] elements) {
//		新数组的长度要比放入数据的数组长度大一个,因为新数组中从下标为1开始存储
		elementData=new Object[elements.length+1];
		for(int i=0,index=1;i<elements.length;i++,index++) {
			elementData[index]=elements[i];
		}
	}
//	获取指定下标处的元素
	public E get(int index) {
		return (E) elementData[index];
	}
	
//	获取指定下标的左孩子
	public E left(int index) throws Exception {
//		index<<1  即2倍的index,一个子节点的下标的二倍是他的左孩子结点,如果2倍的index大于等于数组长度则没有左子孩子
		if((index<<1)>=elementData.length) {
			throw new Exception("没有左孩子");
		}
		return (E) elementData[index<<1];
	}
	
//	获取指定下标的右孩子
	public E right(int index) throws Exception {
		if((index<<1)+1>=elementData.length) {
			throw new Exception("没有右孩子");
		}
		return (E) elementData[(index<<1)+1];
	}

}

(2)链式存储 

二叉树的链式存储依靠指针将各个结点串联起来,不需要连续的存储空间。

每个结点包括3个属性:

  • 数据 Data
  • 左孩子结点指针 Left
  • 右孩子结点 Right

链式存储二叉树.png

//二叉树的链式存储
public class BinaryTree<E> {
//	根节点
	TreeNode<E> root;
	
	public BinaryTree(E val) {
		root=new TreeNode<E>(val);
	}
//	结点类
	static class TreeNode<E>{
		E data;
		TreeNode<E> left;
		TreeNode<E> right;
		
		public TreeNode() {
			
		}
		public TreeNode(E val) {
			this.data=val;
		}
	}
	
	public TreeNode<E> left(TreeNode<E> parent,E val){
		TreeNode<E> newNode=new TreeNode<E>(val);
		parent.left=newNode;
		return newNode;
	}
	
	public TreeNode<E> right(TreeNode<E> parent,E val){
		TreeNode<E> newNode=new TreeNode<E>(val);
		parent.right=newNode;
		return newNode;
	}
	

}

四、二叉树的遍历

前序遍历根结点->左子树->右子树
中序遍历左子树->根结点->右子树
后序遍历左子树->右子树->根结点

(1)前序遍历

先序遍历.png

	public static void preOrder(TreeNode root) {
		if(root==null) {
			return;
		}
		System.out.print(root.data);
		preOrder(root.left);
		preOrder(root.right);
	}

(2)中序遍历 

中序遍历.png

public static void inOrder(TreeNode root) {
		if(root==null) {
			return;
		}
		inOrder(root.left);
		System.out.print(root.data);
		inOrder(root.right);
	}

 (3)后序遍历

后序遍历.png

public static void postOrder(TreeNode root) {
		if(root==null) {
			return;
		}
		postOrder(root.left);
		postOrder(root.right);
		System.out.print(root.data);
	}

 (4)层序遍历

层序遍历,就是按二叉树从上到下,从左到右,依次打印每层中每个结点存储的数据

image.png

public static void levelOrder(TreeNode root) {
		
		if(root==null) {
			return;
		}
		Queue<TreeNode> queue=new LinkedList<TreeNode>();
		queue.offer(root);
		while(true) {
			TreeNode t=queue.poll();
			if(t==null) {
				break;
			}
//访问当前节点,就用打印表示访问即可
			System.out.print(t.data);
			if(t.left!=null) {
				queue.offer(t.left);
			}
			if(t.right!=null) {
				queue.offer(t.right);
			}
		}
		
	}

五、二叉查找树

二叉查找树也称为二叉排序树,即BST,是一种特殊的二叉树,它具备以下特点:

1、若左子树不空,则左子树上所有结点的值均小于或等于它的根结点的值

2、若右子树不空,则右子树上所有结点的值均大于或等于它的根结点的值。

3、左、右子树也分为二叉排序树

image.png

二叉查找树的优势在于可以快速查找。 

(1)二叉查找树的基本结构

public class BST {
//	根结点
	TreeNode root;
	
//	树内部类
	static class TreeNode{
		Integer data;//结点数据
		TreeNode left;//左子结点
		TreeNode rigth;//右子结点
		TreeNode parent;//父结点
		
		public TreeNode() {
			
		}
		public TreeNode(Integer val) {
			this.data=val;
		}
	}

}

(2)插入结点实现

//	插入新结点
	public void insert(TreeNode newNode) {
//		默认使用根结点
		TreeNode currentNode=this.root;
//		新结点的父结点
		TreeNode parentNode=null;
//		查找新结点的父结点
		while(currentNode!=null) {
			parentNode=currentNode;
			if(newNode.data>currentNode.data) {
//				右
				currentNode=currentNode.right;
			}else {
//				左
				currentNode=currentNode.left;
			}
		}
		
//		设置新结点的父结点
		newNode.parent=parentNode;
		
//		判断当前树是否为空树
		if(parentNode==null) {
			this.root=newNode;
		}else {
//			保存新结点
			if(parentNode.data<newNode.data) {
				parentNode.right=newNode;
			}else {
				parentNode.left=newNode;
			}
		}
	}

(3)初始化BST

public void init(int[] array) {
		for(int n:array) {
			insert(new TreeNode(n));
		}
	}

(4)查找结点

//	查找结点
	public TreeNode search(TreeNode parentNode,int data) {
		if(parentNode==null) {
			return parentNode;
		}
		if(data<parentNode.data) {
			return search(parentNode.left,data);
		}else if(data>parentNode.data){
			return search(parentNode.right,data);
		}else {
			return parentNode;
		}
	}

(5)查找最大值

//	查找最大值
	public TreeNode findMax(TreeNode currentNode) {
		if(currentNode==null) {
			return currentNode;
		}
		TreeNode parent=null;
		while(currentNode!=null) {
			parent=currentNode;
			currentNode=currentNode.rigth;
		}
		return parent;
	}

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

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

相关文章

nodejs 16版本

Index of /download/release/latest-v16.x/

医院内网多台主机中毒流量分析案例

背景 最近医院的医生多次反馈网络出现慢和卡顿现象。医院十分重视这个问题&#xff0c;并将之反馈给网络部门同事进行处理。经过多次排查和分析&#xff0c;并没有发现网络中的异常情况。为了更好地解决这一问题&#xff0c;我们推荐安装NetInside流量分析系统。这个系统可以对…

c++视觉图像----扩充边界

图像扩充边界 #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp>int main() {// 读取图像cv::Mat image cv::imread("1.jpg", cv::IMREAD_COLOR);if (image.empty()) {std::cerr << "Could not open or find the imag…

【JVM--StringTable字符串常量池】

文章目录 1. String 的基本特性2. 字符串拼接操作3. intern()的使用4. StringTable 的垃圾回收 1. String 的基本特性 String 声明为 final 的&#xff0c;不可被继承String 实现了 Serializable 接口&#xff1a;表示字符串是支持序列化的。String 实现了 Comparable 接口&am…

求臻人故事 | 在求臻医学的沃土中,我像竹子般茁壮成长

在这个快节奏的社会中&#xff0c;我们时常忽略了身边的“小人物”&#xff0c;他们或许默默无闻&#xff0c;或许平凡无奇&#xff0c;但他们的经历、奋斗和成就&#xff0c;却能给我们带来深深的启示。让我们一起走进每个平凡的求臻人世界&#xff0c;聆听他们的“大故事”&a…

Direct3D网格(一)

创建网格 我们可以用D3DXCreateMeshFVF函数创建一个"空"网格对象 &#xff0c;空网格对象是指我们指定了网格的面片总数和顶点总数&#xff0c;然后由该函数为顶点缓存、索引缓存和属性缓存分配大小合适的内存&#xff0c;之后即可手工填入网格数据。 HRESULT WINA…

供水管网监测系统

随着城市人口的不断增长和经济的快速发展&#xff0c;供水管网的安全和可靠性变得尤为重要。在过去&#xff0c;供水管网的监测往往是依靠人工巡查&#xff0c;这种方式不仅费时费力&#xff0c;而且容易出现疏漏和盲区。然而&#xff0c;随着科技的进步&#xff0c;供水管网监…

【算法|动态规划No.16】leetcode931. 下降路径最小和

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【手撕算法系列专栏】【LeetCode】 &#x1f354;本专栏旨在提高自己算法能力的同时&#xff0c;记录一下自己的学习过程&#xff0c;希望…

智能售后工单系统是什么?智能工单系统有什么用?

对于传统的客服问题处理机制中&#xff0c;如果使用智能工单详细记录客户的问题以及解决问题的全过程&#xff0c;可以有效地帮助客服中心或业务管理层从总体层面了解客户的问题&#xff0c;给出有效的解决方案以及处理问题的紧急程度。从每个服务分支到问题&#xff0c;基于大…

361154-30-5|点击糖化学试剂Ac4ManNAz

产品简介&#xff1a;N-叠氮乙酰基甘露糖胺-三酰化&#xff08;AC4MANAZ&#xff09;可用作标记试剂&#xff0c;点击糖化学试剂&#xff0c;叠氮化物基团允许它与炔烃反应&#xff0c;是一种含叠氮的代谢糖蛋白标记试剂&#xff0c;叠氮化物修饰的蛋白质可以通过与炔烃反应检测…

基于springboot实现自习室预订系统的设计与实现项目【项目源码+论文说明】分享

基于springboot实现自习室预订系统的设计与实现演示 摘要 在网络高速发展的时代&#xff0c;众多的软件被开发出来&#xff0c;给学生带来了很大的选择余地&#xff0c;而且人们越来越追求更个性的需求。在这种时代背景下&#xff0c;学院只能以学生为导向&#xff0c;所以自习…

软件工程师都应该知道的10个定律

一、海勒姆法则 内容 当一个 API 有足够多的用户&#xff0c;你在契约中承诺了什么并不重要&#xff1a;系统中所有看得见的行为都会有某个人依赖…… 案例 现在有两个系统A和B&#xff0c;B的一个接口返回一个列表。A系统的开发人员发现返回的列表都是按照ID正向排序的。本…

SSH版本信息可被获取

漏洞描述 Name SSH版本信息可被获取 Description SSH服务允许远程攻击者获得ssh的具体信息&#xff0c;如版本号等等。这可能为攻击者发动进一步攻击提供帮助。 CVE No. CVE-1999-0634 分析结果 该问题不属于漏洞&#xff0c;不存在安全风险。SSH协议是一种安全协议&am…

基于Springboot实现幼儿园管理系统项目【项目源码+论文说明】

基于Springboot实现幼儿园管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;各行各业都在努力与现代先进技术接轨&#xff0c;通过科技手段提高自身的优势&#xff1b;对于幼儿园管理系统当然也不能排除在外&#xff0c;随着网络技术的不断成熟&#xff0c;带动了幼儿园管…

【PickerView案例13-应用程序对象介绍 Objective-C语言】

一、应用程序对象介绍: 1.应用程序对象介绍: 应用程序介绍: 应用程序介绍: 应用程序介绍: 应用程序启动,本身这一过程,不是应用程序启动就完事儿了, 它有一些比较细节的东西,比如说: 1)info.plist以及pch文件 2)UIApplication对象 这个呢,我们都是分开的去说,…

C语言进阶文件操作

本章重点 1. 为什么使用文件 2. 什么是文件 3. 文件的打开和关闭 4. 文件的顺序读写 5. 文件的随机读写 6. 文本文件和二进制文件 7. 文件读取结束的判定 8. 文件缓冲区 目录 1. 为什么使用文件 2. 什么是文件 2.1 程序文件 2.2 数据文件 2.3 文件名 3. 文…

分布式软件架构——服务端缓存的三种属性

服务端缓存 在透明多级分流系统中&#xff0c;我们以流量从客户端中发出开始&#xff0c;以流量到达服务器集群中真正处理业务的节点结束。一起探索了在这个过程中与业务无关的一些通用组件&#xff0c;包括DNS、CDN、客户端缓存&#xff0c;等等。 实际上&#xff0c;服务端缓…

Docker搭建Redis cluster集群

redis常用的三种集群方式是&#xff1a;主从复制&#xff0c;sentinel 哨兵模式&#xff0c;cluster模式&#xff0c;本节我想详细记录下cluster集群的动手部署方式。cluster是比较主流的方式&#xff0c;优缺点可以百度查下。 Redis-Cluster采用无中心结构&#xff0c;每个节…

Hadoop启动缺失ResourceManager

Hadoop启动缺失ResourceManager 查日志是resourcemanager空指针&#xff0c;java.lang.NullPointerException 1、进入根目录的tmp文件夹 cd /tmp2、删除hadoop-yarn-root rm -rf hadoop-yarn-root3、重启hadoop就好啦&#xff01;&#xff01;&#xff01;&#xff01;&…

三网运营商大数据精准营销客源信息提取的原理是什么?

现在的这个互联网时代&#xff0c;越来越多的人从事运营商大数据这个行业&#xff0c;相信大家都很好奇运营商大数据的绝对优势究竟是什么&#xff0c;它究竟是有什么魅力&#xff0c;能够让那么多的人为它所倾倒&#xff0c;下面我们就来看一下它究竟有什么优势吧。 1.对用户的…