java树算法_Java数据结构算法(三)树

31fcc5c45981

本文旨作于收集整理使用!!

导航

一、树

树(Tree)是n(n≥0)个结点的有限集,n=0称之为空树。在非空树种:当有且仅有一个特定的称为根(Root)的结点; 其余结点可以划分为m(m>0)个互不相交的有限集T1、T2 、…、Tm,每个集Ti(1≤i≤m)均为树,且称为树的子树(SubTree), 如下图所示。

31fcc5c45981

根节点:根节点指没有双亲结点的结点,一棵树中最多有一个根节点(如A)

叶子结点:没有孩子结点的结点叫作叶子结点(如L、M、F)

兄弟结点:拥有相同双亲结点的所有孩子结点叫作兄弟结点(L、M是E的兄弟结点,I、J、K是D的兄弟结点)

结点的深度:是指从根节点到该节点的路径长度(O点的深度为3,A—C—G—O)

树的高度:是树中所有结点高度的最大值,树的深度是树中所有结点深度的最大值,对于同一棵树,其深度和高度是相同的,但是对于各个结点,其深度和高度不一定相同

二、二叉树

二叉树(Binary Tree)是n(n>=0)个节点的有限集合,该集合或为空集,或为由一个根节点和两颗互不相交的,分别称为根节点的左子树和右子树的二叉树组成。

31fcc5c45981

二叉树

所有节点只有左子树的二叉树称为左斜树,只有右子树的二叉树称为右斜树。

所有节点均含左子树和右子树,这样的二叉树称为满二叉树。

31fcc5c45981

满二叉树

完全二叉树:若设二叉树的深度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第 h 层所有的结点都连续集中在最左边,这就是完全二叉树。

31fcc5c45981

完全二叉树

二叉树的应用:编译器中的表达式树、用于数据压缩算法中的赫夫曼编码树、支持在集合中查找、插入和删除,其平均时间复杂度为O(lognn)的二叉搜索树(BST)、优先队列(PQ),它支持以对数时间(最坏情况下)对集合中的最小(或最大)数据元素进行搜索和删除;

1、二叉树的存储结构

基本了解了二叉树的组成后,我们学习怎么样去存储二叉树,了解二叉树的存储结构。

1.1、满二叉树

存储满二叉树可以使用数组,我们将上图中的满二叉树存储为数组为[A,B,C,D,E,F,G]),当然我们通过数组复原二叉树时也可以按照顺序复原二叉树。

1.2、完全二叉树

完全二叉树和满二叉树的存储方法相同,上图中的完全二叉树转换为数组([A,B,C,D,E,F,G,H,I])(图中最后的H为I)。

1.2、其他二叉树

有的二叉树既不是满二叉树又不是完全二叉树该如何存储?我们可以将缺少的二叉树的叶子节点用一些特殊的符号存储,将其转换为完全二叉树,如下图所示。

31fcc5c45981

则如上图中的二叉树转换为数组([A,B,C,D,E,F,G,#.#,H,#,#,#,I,J])

2二叉树的遍历

二叉树的遍历分为前序遍历、中序遍历和后序遍历

3.1 前序遍历

先遍历左子树,再遍历右子树

31fcc5c45981

2.2、 中序遍历

从根结点开始(注意并不是先访问根结点),中序遍历根结点的左子树,然后是访问根结点,最后中序遍历右子树

31fcc5c45981

2.3 后序遍历

从左到右先叶子后结点的方式遍历访问左右子树,最后是访问根结点

31fcc5c45981

3、实现二叉树

如下,需要构建如下二叉树,并实现其三种遍历方法

31fcc5c45981

/**

* 构造如下二叉树

* A

* B C

* D E G

*

*/

import java.util.List;

/**

* 构造如下二叉树

* A

* B C

* D E G

*/

public class BinaryTree {

TreeNode root = null;

public BinaryTree() {

root = new TreeNode(0, "A");

}

/**

* 传统方法构造二叉树

*/

public void createBinaryTree() {

TreeNode nodeB = new TreeNode(2, "B");

TreeNode nodeC = new TreeNode(3, "C");

TreeNode nodeD = new TreeNode(4, "D");

TreeNode nodeE = new TreeNode(5, "E");

TreeNode nodeF = new TreeNode(6, "F");

root.leftChild = nodeB;

root.rightChild = nodeC;

nodeB.leftChild = nodeD;

nodeB.rightChild = nodeE;

nodeC.rightChild = nodeF;

}

/**

* 出入二叉树的数组,创建二叉树

*

* @param size 二叉树所有节点的数量和

* @param datas 二叉树的List集合

* @return 返回创建的节点

*/

public TreeNode createBinerTree(int size, List datas) {

TreeNode node = null;

if (datas.size() == 0) {

return null;

}

String data = datas.get(0);

if ("#".equals(data)) {

datas.remove(0);

return node;

}

int index = size - datas.size();

node = new TreeNode(index, data);

if (index == 0) {

root = node;

}

datas.remove(0);

node.leftChild = createBinerTree(size, datas);

node.rightChild = createBinerTree(size, datas);

return node;

}

/**

* 前序遍历

*/

public void preOrder(TreeNode node) {

if (node == null) {

return;

} else {

System.out.println("preOrder data:" + node.getData());

preOrder(node.leftChild);

preOrder(node.rightChild);

}

}

/**

* 中序遍历

*/

public void midOrder(TreeNode node) {

if (node == null) {

return;

} else {

midOrder(node.leftChild);

System.out.println("midOrder data:" + node.getData());

midOrder(node.rightChild);

}

}

/**

* 后序遍历

*/

public void postOrder(TreeNode node) {

if (node == null) {

return;

} else {

preOrder(node.leftChild);

preOrder(node.rightChild);

System.out.println("postOrder data:" + node.getData());

}

}

class TreeNode {

private int index;

private String data;

private TreeNode leftChild;

private TreeNode rightChild;

public TreeNode(int index, String data) {

this.index = index;

this.data = data;

}

public TreeNode getLeftChild() {

return leftChild;

}

public void setLeftChild(TreeNode leftChild) {

this.leftChild = leftChild;

}

public TreeNode getRightChild() {

return rightChild;

}

public void setRightChild(TreeNode rightChild) {

this.rightChild = rightChild;

}

public int getIndex() {

return index;

}

public void setIndex(int index) {

this.index = index;

}

public String getData() {

return data;

}

public void setData(String data) {

this.data = data;

}

}

}

传入数组测试

public class test {

public static void main(String[] args) {

BinaryTree binaryTree=new BinaryTree();

String data[]={"A","B","C","D","E","#","F"};

ArrayListdatas=new ArrayList<>(Arrays.asList(data));

binaryTree.createBinerTree(datas.size(), datas);

binaryTree.preOrder(binaryTree.root);

}

}

结果

preOrder data:A

preOrder data:B

preOrder data:C

preOrder data:D

preOrder data:E

preOrder data:F

三、搜索二叉树

二叉查找树(又:二叉搜索树,二叉排序树),它或者是一棵空树,或者是具有下列性质的二叉树: 若它的左子树不空,则左子树上所有结点的值均小于它的根结点的值; 若它的右子树不空,则右子树上所有结点的值均大于它的根结点的值; 它的左、右子树也分别为二叉排序树。二叉排序树的查找过程和次优二叉树类似,通常采取二叉链表作为二叉排序树的存储结构中序遍历二叉排序树可得到一个关键字的有序序列,一个无序序列可以通过构造一棵二叉排序树变成一个有序序列,构造树的过程即为对无序序列进行排序的过程。每次插入的新的结点都是二叉排序树上新的叶子结点,在进行插入操作时,不必移动其它结点,只需改动某个结点的指针,由空变为非空即可

1、搜索二叉树的实现

/**

* Author: Active_Loser

* Date: 2018/7/30 23:17

* Content: 实现搜索二叉树的建立、添加、删除等操作

*/

public class SearchBinryTree {

public TreeNode root;

public TreeNode put(int data) {

TreeNode node;

TreeNode parent = null;

if (root == null) {

node = new TreeNode(data);

root = node;

return node;

}

node = root;

while (node != null) {

parent = node;

if (data > parent.data) {

node = parent.rightChild;

} else if (data < parent.data) {

node = parent.leftChild;

} else {

return node;

}

}

node = new TreeNode(data);

if (data < parent.data) {

parent.leftChild = node;

node.parent = parent;

} else if (data > parent.data) {

parent.rightChild = node;

node.parent = parent;

}

return node;

}

public TreeNode search(int value) {

TreeNode node = root;

while (node != null && node.data != value) {

if (node.data > value) {

node = node.rightChild;

} else if (node.data < value) {

node = node.leftChild;

}

}

return node;

}

/**

* @param value 删除的数值

* @return 返回删除的节点

*/

public TreeNode delete(int value) {

//判断是否包含需要删除的数

TreeNode deleteNode = search(value);

if (null == deleteNode) {

return null;

}else {

delete(deleteNode);

}

}

private void delete(TreeNode node) {

if (node==null){

return null;

}

TreeNode parent=node.parent;

//做节点与有节点皆为NULL

if (node.leftChild==null&&node.rightChild==null){

if (parent.leftChild==node){

parent.leftChild=null;

}else {

parent.rightChild=null;

}

return;

}

//有左节点没有右节点1.父节点的左节点2.父节点的右节点

if (node.leftChild!=null&&node.rightChild==null){

if (parent.leftChild==node){

parent.leftChild=node.leftChild;

}else if (parent.rightChild==node){

parent.rightChild=node.leftChild;

}

return;

}

//有右节点没有左节点1.父节点的左节点2.父节点的右节点

if (node.leftChild!=null&&node.rightChild==null){

if (parent.leftChild==node){

parent.leftChild=node.rightChild;

}else if (parent.rightChild==node){

parent.rightChild=node.rightChild;

}

return;

}

//既有左节点也有右节点

//获取删除节点的后继节点

TreeNode next=getNextNode(node);

delete(next);

node.data=next.data;

}

private TreeNode getNextNode(TreeNode node) {

if (node==null){

return null;

}else {

if (node.rightChild!=null){

return getMinTreeNode(node.rightChild);

}else {

TreeNode parent=node.parent;

while (parent!=null&&node==parent.rightChild){

node=parent;

parent=parent.parent;

}

return parent;

}

}

return null;

}

//右子树最小值,左子树最大值

public TreeNode getMinTreeNode(TreeNode node){

if (node==null){

return null;

}else {

while (node.leftChild !=null){

node=node.leftChild;

}

}

return node;

}

public void midOrder(TreeNode node) {

if (node == null) {

return;

} else {

midOrder(node.leftChild);

System.out.println("midOrder:" + node.data);

midOrder(node.rightChild);

}

}

class TreeNode {

private TreeNode leftChild;

private TreeNode rightChild;

private TreeNode parent;

private int data;

public TreeNode(int data) {

this.data = data;

}

public TreeNode getLeftChild() {

return leftChild;

}

public void setLeftChild(TreeNode leftChild) {

this.leftChild = leftChild;

}

public TreeNode getRightChild() {

return rightChild;

}

public void setRightChild(TreeNode rightChild) {

this.rightChild = rightChild;

}

public TreeNode getParent() {

return parent;

}

public void setParent(TreeNode parent) {

this.parent = parent;

}

public int getData() {

return data;

}

public void setData(int data) {

this.data = data;

}

}

}

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

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

相关文章

Blazor VS 传统Web应用程序

原文作者: Christian Findlay原文链接&#xff1a;https://christianfindlay.com/2020/07/09/blazor-vs-traditional-web-apps/Blazor是Microsoft团队开发的单页面应用程序&#xff08;SPA&#xff09;框架&#xff0c;它是与React&#xff0c;Angular和Vue.js有相同之处&#…

java 并发 面试题_阿里面试官总结10个经典技术题:Java多线程与并发面试题

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼5&#xff0c;有哪些不同的线程生命周期&#xff1f;当我们在Java程序中新建一个线程时&#xff0c;它的状态是New。当我们调用线程的start()方法时&#xff0c;状态被改变为Runnable。线程调度器会为Runnable线程池中的线程分配CP…

如何在 Web Forms 中引入依赖注入机制

依赖注入技术就是将一个对象注入到一个需要它的对象中&#xff0c;同时它也是控制反转的一种实现&#xff0c;显而易见&#xff0c;这样可以实现对象之间的解耦并且更方便测试和维护&#xff0c;依赖注入的原则早已经指出了&#xff0c;应用程序的高层模块不依赖于低层模块&…

Gentle.Net学习笔记四:修改代码,使用Oracle数据库

开始使用Gentle.Net的时候,我使用编译好的类库,可是不久就发现,如果要更好的利用Gentle.Net,你就不得不做一些修改,所以,还是使用源代码的方式为好. 使用源代码,Gentle.Net作为三个项目添加的解决方案中, Gentle.Common;Gentle.FrameWork;Gentle.Provider.Oracle (根据项目的…

python网页动图_python,tensorflow线性回归Django网页显示Gif动态图

1.工程组成2.urls.py"""Django_machine_learning_linear_regression URL ConfigurationThe urlpatterns list routes URLs to views. For more information please see:https://docs.djangoproject.com/en/2.1/topics/http/urls/Examples:Function views1. Add …

asp.net core集成CKEditor实现图片上传功能

背景本文为大家分享了asp.net core 如何集成CKEditor &#xff0c;并实现图片上传功能的具体方法&#xff0c;供大家参考&#xff0c;具体内容如下。准备工作1.visual studio 2019 开发环境2.net core 2.0 及以上版本实现方法1、新建asp.net core web项目2、下载CKEditor这里我…

ValidationSummary 控件

真是有些郁闷到现在这个控件还一直没有用过.. 直到今天才发现.可以解决错误信息提示排版上的问题. 单独用RequiredFieldValidator 我以前一直没有设Text属性.结果一错误就是errormessage这边就出来了设了text后就不会显示errormessage 而显示Text了这个时候如果有ValidationSum…

java static new_java静态类new的对象是否能被回收?

问题来自一个线上GC频繁的应用&#xff0c;观察到老年代一直gc下不去导致应用被gc STW卡主假死&#xff0c;检查代码发现这样一段代码&#xff0c;感觉可疑代码如下&#xff1a;public class WriteEsWork {public static void write(List<EsIndexInfo> esList, String in…

看了一天小说

在公司呆了一天什么都没干&#xff0c;看了一天小说。都不知道自己啥时候变得这么堕落的&#xff0c;不过还好&#xff0c;至少小说是我喜欢看的那种&#xff0c;很热血的小说。不会有主管看到我的Blog吧&#xff0c; 明天要干点正事了&#xff0c;还是得跟自己说一下&#xff…

Blazor VS React / Angular / Vue.js

原文作者: Christian Findlay原文链接&#xff1a;https://christianfindlay.com/2020/06/04/blazor-vs-react-angular-vue-js/Blazor是一项新的Microsoft技术&#xff0c;允许开发人员使用C&#xff03;为浏览器编写代码, 本文将Blazor与其他三个常见SPA框架进行了比较&#x…

c语言的使用比例远远高于python语言对吗_Python和C语言的语法有什么不同?

随着经济发发展&#xff0c;互联网精英的缺乏越来越严重了&#xff0c;尤其是编程工程师&#xff0c;市场缺乏率极高&#xff0c;所有对于准备即将学习编程朋友&#xff0c;是一个非常的好时机Python和C语言的语法有什么不同&#xff1f;python与C的区别如下&#xff1a;1、语言…

ASP.NET 應用程式的安全性模型

本單元內容 功能 ASP.NET 應用程式依賴於許多不同元素及技術的成功交互操作。每個方案元件都提供安全性功能&#xff0c;以滿足其自身的需求。然而&#xff0c;純粹從個別元件的角度考量安全性還不夠。若要提供整體方案的安全性&#xff0c;您還必須考量元件如何彼此互動。 本單…

.NET开源5年了,这些宝藏你还没get?

从2016年微软发布.NET Core1.0&#xff0c;至今.NET开源也快5年了&#xff0c;GitHub也涌现了很多优秀的开源项目&#xff0c;关于CLR层面调优的讨论也多了起来&#xff0c;尤其是龙芯.NET开源的CLR迁移项目&#xff0c;更是让.NET进入一个全新的时代。鲁迅说过&#xff1a;菜鸟…

java socket send_java socket编程

TcpServerServer端所要做的事情主要是建立一个通信的端点&#xff0c;然后等待客户端发送的请求。典型的处理步骤如下&#xff1a;1. 构建一个ServerSocket实例&#xff0c;指定本地的端口。这个socket就是用来监听指定端口的连接请求的。2. 调用socket的accept()方法来获得下面…

C#来创建和读取XML文档 [转]

C&#xff03;来创建和读取XML文档【关键词】&#xff1a;XML 录入&#xff1a;小鱼之家 来源&#xff1a;http://fisher.xundain.com 时间&#xff1a;2005-3-3 23:41:54 点击&#xff1a;85次 扩展标记语言XML&#xff08;eXtensible Markup Language&#xff09;&#xff0…

如何成功搞垮一个团队?

阅读本文大概需要3分钟。最近好几个读者聊到是否能写一些怎么带团队的文章&#xff0c;在互联网职场中&#xff0c;升职带团队被大部分职场人视为职业生涯的重大转折点。一方面&#xff0c;升职意味着更丰厚的待遇&#xff0c;另一方面&#xff0c;带团队意味着自己大小变成了一…

Python学习第一天

干程序这行比较辛苦的就是要随时更新自己的知识。闷&#xff5e;&#xff5e;为了让自己能够更加深入的学习GUN和LINUX。在简单了解了shell以后决定学习Python。&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d;&#xff0d…

WinForm捕获全局异常(捕获未处理的异常)

背景我们在做WinForm程序的时候&#xff0c;一般都是对异常进行处理&#xff0c;但是&#xff0c;我们要防止不小心出现未知异常&#xff0c;导致软件崩溃。也可采集系统未知的异常信息&#xff0c;防止出现异常&#xff0c;也无法下手。于是就有了如这篇文章标题所述的一个简单…

it's so cold

今晚值日&#xff0c;本来中午不冷的&#xff0c;就换了衬衫&#xff0c;结果傍晚的时候就很凉&#xff0c;吃过晚饭只好回去换了件秋天的棉衫。但晚上我值日的那个地方风很大&#xff0c;熬了一节课&#xff0c;下课学生来打乒乓&#xff0c;借了件他们的校服穿&#xff0c;结…

java 继承 冒号_java继承(extends)简单介绍

继承相信很多人都有听说过&#xff0c;继承是面向对象的三个基本特征之一&#xff0c;下面的话就一起通过简单的文章来对java继承进行一下了解吧。继承和现实生活中的“继承”的相似之处是保留一些父辈的特性&#xff0c;从而减少代码冗余&#xff0c;提高程序运行效率。Java中…