因为是跟着视频学的所以这个地方也就分为两个部分了

基础部分

为什么需要树这种数据结构

1.先说数组存储的方式吧,我们都知道,数组有很多排序算法,也有常见的查找算法,这使我们操作起来很方便,但是呢,我们发现其实这种方便也仅仅是在于查找,排序那种简单类型的,遇到对象类型的就比较麻烦,而且插入的时候会整体移动效率比较低

2.链式存储方式,在一定程度上对数组的存储方式进行了改善,比如插入某个值,我们只需要将插入的节点连接到表中即可删除的效率也很高,但是他的查询检索效率对应的就低下来了,比如检索某个值,需要从头开始便利

详细的说数组存储方式

我们要想在数组中插入一个数据,我们都知道数组一开始是事先分配好空间的,我们要想在原数组中插入新的数据,需要进行一个数组扩容,这个数组扩容规定每次在底层都需要创建新的数组要将原来的数据拷贝到数组,并插入新的数据,我们常见的那个ArrayList数组底层也是维护了一个Object数组(他也是这种方式扩容(只是方法不同))

我找了下老师关于ArrayList数组底层笔记

  1. ArrayList中维护了一个Object类型的数组elementData. [debug看源码]
  2. 当创建对象时,如果使用的是无参构造器,则初始elementData容量为0 (jdk7 是10)
  3. 如果使用的是指定容量capacity的构造器,则初始elementData容量为capacity.
  4. 当添加元素时:先判断是否需要扩容,如果需要扩容,则调用grow方法,香则直接添加元素到合适位置
  5. 如果使用的是无参构造器,如果第一次添加, 需要扩容的话,则打容elementData为10如果需要再次扩容的话,则扩容elementData为1.5倍。
  6. 如果使用的是指定容量capacity的构造器,如果需要扩容,则直接扩容elementData为1.5倍
//以ArrayList为例,展示怎么扩容
//2021年1月24日22:04:07
//@author 王
public class Test {public static void main(String[] args) {ArrayList arrayList = new ArrayList();/*** Constructs an empty list with an initial capacity of ten.*/
//      public ArrayList() {//          this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;//    private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};他是一个空数组
//      }/*** ArrayList底层仍然是数组扩容*//*** 机制* *//*** Increases the capacity to ensure that it can hold at least the* number of elements specified by the minimum capacity argument.** @param minCapacity the desired minimum capacity*/private void grow(int minCapacity) {// overflow-conscious codeint oldCapacity = elementData.length;int newCapacity = oldCapacity + (oldCapacity >> 1);if (newCapacity - minCapacity < 0)newCapacity = minCapacity;if (newCapacity - MAX_ARRAY_SIZE > 0)newCapacity = hugeCapacity(minCapacity);// minCapacity is usually close to size, so this is a win:elementData = Arrays.copyOf(elementData, newCapacity);}}
}

grow就是他的扩容方法

那我们的链表呢?链表插入操作就很简单了,只需要把上一个元素的指针指向我们待添加的元素就行了,待添加的元素的指针指向原来的下一个

树存储方式

通俗的来讲,他就是既优化了查询,又优化了增删操作

那如果以二叉排序树来存储数据,流程是什么?为什么两者都优化了?

以老师的数组举例,{7,3,10,1,5,9,12},那么二叉排序树的结构就是

查找操作是不是简单了?比7大的直接去右边子树查找,有点折半的意思了吧,比我们最平常的查找是不是快

添加呢?加入添加14,哪找位置就是定位到了12,比12大那么应该插入到12的右子树上,删除呢?删除同样也是这么快速

不言而喻,他的好处我们都能感觉到了

常用术语

至于树的形状,就不在这里说了

里面有这几个名词

1.节点 通俗讲就是每一个数据

2.根节点 就是最上面那个第一层的那个节点

3.父节点 该节点的直接上级节点

4.子节点 该节点的直接下级节点

5.叶子结点 就是没有子节点了,最后一层的节点肯定是叶子节点,也有可能在其它层

6.节点的权 就是节点值

7.路径 从根节点找到目标节点的路线

8.层

9.子树

10.数的高度 最大层数

11.森林 多颗子树构成森林

二叉树

每个节点最多只能有两个子节点的一种形式的树

关于二叉树的一些特点有必要记一下

1.如果该二叉树的所有叶子节点都在最后一层,并且结点总数= 2^n-1,n为层数,则我们称为满二叉树

2.如果该二叉树的所有叶子节点都在最后一层或者倒数第二层,而且最后一层的叶子节点在左边连续倒数第二层的叶子节点在右边连续,我们称为完全二叉树

二叉树的遍历

前序遍历:先输出父节点,再遍历子节点

中序遍历:先遍历左子树,在输出父节点,在遍历右子树

后序遍历:先遍历左子树,再便利右子树,最后输出父节点

所以我们可以通过父节点输出的顺序,确定是那种遍历方式

代码

我们需要创建的数是这样的

那么上代码

先是我们的节点代码

//先创建HeroNode节点
class HeroNode{private int no;private String name;private HeroNode left;private HeroNode right;public HeroNode(int no, String name) {super();this.no = no;this.name = name;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}public HeroNode getLeft() {return left;}public void setLeft(HeroNode left) {this.left = left;}public HeroNode getRight() {return right;}public void setRight(HeroNode right) {this.right = right;}@Overridepublic String toString() {return "HeroNode [no=" + no + ", name=" + name + "]";}//编写前序遍历方法public void preOrder(){System.out.println(this);//先输出父节点//递归向左子树前序遍历if(this.left != null){this.left.preOrder();}//递归向右子树前序遍历if(this.right != null){this.right.preOrder();}}//中序遍历public void infixOrder(){//递归向左子树中序遍历if(this.left != null){this.left.infixOrder();}System.out.println(this);//输出父节点//向右递归中序遍历子树if(this.right != null){this.right.infixOrder();}}//后序遍历public void postOrder(){if(this.left != null){this.left.postOrder();}if(this.right != null){this.right.postOrder();}System.out.println(this);//输出父节点}}

我们的节点写出来之后就是我们的树跟节点怎么关联呢?——》定义我们的二叉树

//定义一个BinnaryTree二叉树
class BinnaryTreeDemo{private HeroNode root;public void setRoot(HeroNode root) {this.root = root;}//前序遍历public void preOrder(){if(this.root != null){this.root.preOrder();}else{System.out.println("二叉树为空,无法遍历");}}//中序遍历public void infixOrder(){if(this.root != null){this.root.infixOrder();}else{System.out.println("二叉树为空,无法遍历");}}//中序遍历public void postOrder(){if(this.root != null){this.root.postOrder();}else{System.out.println("二叉树为空,无法遍历");}}}

这样我们就可以通过setRoot方法跟我们的节点关联起来了,我们的树就可以创建了

测试代码

package 树;
//二叉树的前序、中序、后序遍历
//2021年1月25日22:57:42
//@author     王
public class BinnaryTree {public static void main(String[] args) {// TODO Auto-generated method stub//创建一颗二叉树BinnaryTreeDemo binnaryTreeDemo = new BinnaryTreeDemo();//创建节点HeroNode root = new HeroNode(1, "小王");HeroNode node2 = new HeroNode(2, "小胡");HeroNode node3 = new HeroNode(3, "小黄");HeroNode node4 = new HeroNode(4, "老肥");//手动创建二叉树,后面用递归方式创建二叉树root.setLeft(node2);root.setRight(node3);node3.setRight(node4);binnaryTreeDemo.setRoot(root);//测试System.out.println("前序遍历");binnaryTreeDemo.preOrder();System.out.println("中序遍历");binnaryTreeDemo.infixOrder();System.out.println("后序遍历");binnaryTreeDemo.postOrder();}
}

这样最简单的前中后序遍历就出来了,我们看看效果

前序遍历
HeroNode [no=1, name=小王]
HeroNode [no=2, name=小胡]
HeroNode [no=3, name=小黄]
HeroNode [no=4, name=老肥]
中序遍历
HeroNode [no=2, name=小胡]
HeroNode [no=1, name=小王]
HeroNode [no=3, name=小黄]
HeroNode [no=4, name=老肥]
后序遍历
HeroNode [no=2, name=小胡]
HeroNode [no=4, name=老肥]
HeroNode [no=3, name=小黄]
HeroNode [no=1, name=小王]

后续改进下一篇博客笔记在写出来,先把全部代码贴一遍

package 树;
//二叉树的前序、中序、后序遍历
//2021年1月25日22:57:42
//@author     王
public class BinnaryTree {public static void main(String[] args) {// TODO Auto-generated method stub//创建一颗二叉树BinnaryTreeDemo binnaryTreeDemo = new BinnaryTreeDemo();//创建节点HeroNode root = new HeroNode(1, "小王");HeroNode node2 = new HeroNode(2, "小胡");HeroNode node3 = new HeroNode(3, "小黄");HeroNode node4 = new HeroNode(4, "老肥");//手动创建二叉树,后面用递归方式创建二叉树root.setLeft(node2);root.setRight(node3);node3.setRight(node4);binnaryTreeDemo.setRoot(root);//测试System.out.println("前序遍历");binnaryTreeDemo.preOrder();System.out.println("中序遍历");binnaryTreeDemo.infixOrder();System.out.println("后序遍历");binnaryTreeDemo.postOrder();}}
//定义一个BinnaryTree二叉树
class BinnaryTreeDemo{private HeroNode root;public void setRoot(HeroNode root) {this.root = root;}//前序遍历public void preOrder(){if(this.root != null){this.root.preOrder();}else{System.out.println("二叉树为空,无法遍历");}}//中序遍历public void infixOrder(){if(this.root != null){this.root.infixOrder();}else{System.out.println("二叉树为空,无法遍历");}}//中序遍历public void postOrder(){if(this.root != null){this.root.postOrder();}else{System.out.println("二叉树为空,无法遍历");}}}//先创建HeroNode节点
class HeroNode{private int no;private String name;private HeroNode left;private HeroNode right;public HeroNode(int no, String name) {super();this.no = no;this.name = name;}public int getNo() {return no;}public void setNo(int no) {this.no = no;}public String getName() {return name;}public void setName(String name) {this.name = name;}public HeroNode getLeft() {return left;}public void setLeft(HeroNode left) {this.left = left;}public HeroNode getRight() {return right;}public void setRight(HeroNode right) {this.right = right;}@Overridepublic String toString() {return "HeroNode [no=" + no + ", name=" + name + "]";}//编写前序遍历方法public void preOrder(){System.out.println(this);//先输出父节点//递归向左子树前序遍历if(this.left != null){this.left.preOrder();}//递归向右子树前序遍历if(this.right != null){this.right.preOrder();}}//中序遍历public void infixOrder(){//递归向左子树中序遍历if(this.left != null){this.left.infixOrder();}System.out.println(this);//输出父节点//向右递归中序遍历子树if(this.right != null){this.right.infixOrder();}}//后序遍历public void postOrder(){if(this.left != null){this.left.postOrder();}if(this.right != null){this.right.postOrder();}System.out.println(this);//输出父节点}}

树以及树简单的遍历方法相关推荐

  1. python回溯方法的模板_实例讲解Python基于回溯法子集树模板实现图的遍历功能

    这篇文章主要介绍了Python基于回溯法子集树模板实现图的遍历功能,结合实例形式分析了Python使用回溯法子集树模板针对图形遍历问题的相关操作技巧与注意事项,需要的朋友可以参考下 本文实例讲述了Py ...

  2. 树的基本概念和遍历规则 数据结构和算法 二叉树遍历(前序、中序、后序、层次、深度优先、广度优先遍历)

    zsychanpin 博客园 首页 新随笔 联系 订阅 管理 树的基本概念和遍历规则 树的递归定义 树是n(n>0)个结点的有限集,这个集合满足下面条件:       ⑴有且仅有一个结点没有前驱 ...

  3. 树和二叉树(四种遍历,建树)详解+二叉排序树(包含图像和相关习题)

    目录 树和二叉树 一.树 2.有序树和无序树 3.森林 4.树的基本性质 二.二叉树的概念 (1)二叉树的编号 1.二叉树和度为2的有序树的区别: 2.满二叉树 3.完全二叉树: 4.平衡二叉树: 5 ...

  4. python创建树结构、求深度_数据结构-树以及深度、广度优先遍历(递归和非递归,python实现)...

    前面我们介绍了队列.堆栈.链表,你亲自动手实践了吗?今天我们来到了树的部分,树在数据结构中是非常重要的一部分,树的应用有很多很多,树的种类也有很多很多,今天我们就先来创建一个普通的树.其他各种各样的树 ...

  5. Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现

    Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树.二叉查找树的插入节点.二叉查找树的删除.二叉树的遍历.平衡二叉树)C++语言实现 目录 树的基础知识 1.二叉树的遍-前序 ...

  6. 数据结构 多路查找树 ---------B树和B+树的简单介绍

    参考链接:微信公众号 程序员小灰 https://mp.weixin.qq.com/s/rDCEFzoKHIjyHfI_bsz5Rw https://mp.weixin.qq.com/s/jRZMMO ...

  7. 树与图的深度优先遍历

    树与图的深度优先遍历*: 树其实也是图的一种 图: 分为有向图和无向图 图的储存: 第一种:邻接矩阵,就是一个二维数组,缺点:当点和边特别多的时候,存不下,一般用的比较少,而且非常浪费空间 第二种:邻 ...

  8. 麦肯锡逻辑树——快速分析和解决问题的有效方法

    这是阅读<靠谱--顶尖咨询师教你的工作基本功>的第二篇笔记. 作者在第二章"逻辑思考技巧"当中,介绍了一种分析和解决问题的技巧--逻辑树.但是书中所述并不详细,我又阅读 ...

  9. 【数据结构】树与树的表示、二叉树存储结构及其遍历、二叉搜索树、平衡二叉树、堆、哈夫曼树与哈夫曼编码、集合及其运算

    1.树与树的表示 什么是树? 客观世界中许多事物存在层次关系 人类社会家谱 社会组织结构 图书信息管理 分层次组织在管理上具有更高的效率! 数据管理的基本操作之一:查找(根据某个给定关键字K,从集合R ...

  10. php easyui tree 结构,EasyUI Tree树组件无限循环的解决方法

    在学习jquery easyui的tree组件的时候,在url为链接地址的时,发现如果最后一个节点的state为closed时,未节点显示为文件夹,单击会重新加载动态(Url:链接地址)形成无限循环. ...

最新文章

  1. 数据结构第二章线性表学习笔记
  2. xpath IE 7
  3. android通过adb shell播放音乐
  4. 表达式括号匹配(信息学奥赛一本通-T1353)
  5. 小汤学编程之JavaEE学习day08——Maven
  6. ICE专题:实战分布式的Hello Word 【原创】
  7. 一种语音控制PPT翻页系统的制作方法
  8. 白事碰上红事,徐渭应景吟诗
  9. CS5211/eDP转LVDS转换器方案设计电路图
  10. DEL: 华为无线modem变无线路由器 2
  11. 按键精灵学习如何偷菜示例基本代码
  12. Strust2 success sucess
  13. 可变参C API va_list,va_start,va_arg_va_end以及c++可变参模板
  14. 新型肺炎疫情导致华为手机遭受重大挫折,排名滑落两名
  15. 我的世界java版复仇双持_我的世界战备双持2mod整合包
  16. Parametric model
  17. labuladong算法小抄中图算法的学习笔记(c++版)
  18. php怎么获取js值,php 怎么获取JS的值 ,新手折腾几天了 还请大侠赐教
  19. java获取和风天气_SpringMVC结合天气api实现天气查询
  20. 【python练习,6.15】(霍兰德人格分析雷达图等)

热门文章

  1. vue-awesome-swiper:slideTo无效
  2. 论文笔记_S2D.74_2021_ICRA_PENet:面向精确和高效的图像引导的深度补全
  3. 论文笔记_S2D.33_2015-ICCV_使用单个多尺度卷积网络,预测深度、表面法线和语义标签
  4. 论文笔记_S2D.03-2012-BMVC-目标类别分割和稠密立体重建的联合优化
  5. Bug: tf.contrib.checkpoint.NoDependency object
  6. 随笔小杂记(三)——将遥感大图随机分割成小图作为训练集
  7. 一文详解YOLOX算法实现血细胞检测
  8. 科技部正式发文:破除“唯论文”不良导向;网友:靠水论文拿奖励的人不开心了...
  9. #ifndef #define #endif用法理解
  10. web项目搜索框智能提示