树具有的特点有:

(1)每个结点有零个或多个子结点

(2)没有父节点的结点称为根节点

(3)每一个非根结点有且只有一个父节点

(4)除了根结点外,每个子结点可以分为多个不相交的子树。

树的基本术语有:

若一个结点有子树,那么该结点称为子树根的“双亲”,子树的根称为该结点的“孩子”。有相同双亲的结点互为“兄弟”。一个结点的所有子树上的任何结点都是该结点的后裔。从根结点到某个结点的路径上的所有结点都是该结点的祖先。

结点的度:结点拥有的子树的数目

叶子结点:度为0的结点

分支结点:度不为0的结点

树的度:树中结点的最大的度

层次:根结点的层次为1,其余结点的层次等于该结点的双亲结点的层次加1

树的高度:树中结点的最大层次

森林:0个或多个不相交的树组成。对森林加上一个根,森林即成为树;删去根,树即成为森林。

二叉树的性质

a、在非空二叉树的第i层上,至多有2^(i-1)个结点

假设这是一棵满二叉树,则1、2、3层分别有1、2、4个结点,满足以上性质

b、深度为k的二叉树至多有2^k-1个结点

假设这是一棵满二叉树,则4层有15个结点,满足以上的性质

c、对任何一颗二叉树T,如果其终端结点数为n0,度为2的结点数为n2,则n0 = n2+1

假设二叉树中度为1的结点数为n1,因为二叉树只有度为1,2,0的结点,所以有n=n0+n1+n2。再看二叉树分支条数e,因为二叉树除了根结点没有父结点,进入它的边数为0之外,其他每一结点都有一个且仅有一个父结点,进入它们的边数均为1,故二叉树中总的边数为e=n-1=n0+n1+n2-1。又由于每个度为2的结点发出2条边,每个度为1的结点发出1条边,每个度为0的结点发出0条边,因此总的边数e=2n2+1n1+0n0=2n2+n1,由以上两式可以得出n0= n2+1

上图中结点总数是10,n2(1、2、3、4)为4,n1(5)为1,n0(6、7、8、9、10)为5

d、具有n个结点的完全二叉树深度为⌈log2(n+1)⌉,对以2为底n+1对数进行向上取整(⌈⌉是向上取整符号)

可以由性质2得出,深度为k的完全二叉树最多有 n \leq 2{k}-1个结点,最少有2{k-1}-1个,因此:

2^{k-1}-1 < n \leq 2^{k}-1

2^{k-1} < n+1 \leq 2^{k}

k-1 < log_{2}(n+1) \leq k

因为log_{2}(n+1)介于 K-1 和 K之间且不等于 K-1,深度又只能是整数,所以有⌈log_{2}(n+1)⌉

e、如果有一颗有n个结点的完全二叉树的结点按层次序编号,对任一层的结点i(1<=i<=n)有

如果i=1,则结点是二叉树的根,无双亲,如果i>1,则其双亲结点为⌊i/2⌋,向下取整

如果2i>n那么结点i没有左孩子,否则其左孩子为2i

如果2i+1>n那么结点没有右孩子,否则右孩子为2i+1

若结点i为奇数,且i!=1,它处于右兄弟位置,则它的左兄弟结点i-1

若结点i为偶数,且i!=n,它处于左兄弟位置,则它的右兄弟为结点i+1

https://github.com/mcrwayfun/java-data-structure/blob/master/doc/source/tree/树.md#23-二叉树的性质

递归实现二叉树的遍历

前序遍历

基本思想:若二叉树为空,则返回。否则从根结点开始,优先访问根结点,再前序遍历左子树,前序遍历右子树,即根——左——右

class TreeNode{

	int data;
TreeNode leftChild;
TreeNode rightChild;
} /**
* 前序遍历(中左右)
* output:A、B、D、G、H、C、E、I、F
* @param root
*/
public void preOrder(TreeNode root) { if (root == null) {
return;
} else {
System.out.println("preOrder data:" + root.getData());
preOrder(root.leftChild);
preOrder(root.rightChild);
}
}

中序遍历

基本思想:若二叉树为空,则返回。否则优先中序遍历左子树,再访问根结点,再后序遍历右子树,即左——根——右

 /**
* 中序遍历(左中右)
* output:G、D、H、B、A、E、I、C、F
* @param root
*/
public void midOrder(TreeNode root) { if (root == null) {
return;
} else {
midOrder(root.leftChild);
System.out.println("midOrder data:" + root.getData());
midOrder(root.rightChild);
}
}

后序遍历

基本思想:若二叉树为空,则返回。否则优先后序遍历左子树,再后序遍历右子树,最后访问根结点,,即左——右——根

 /**
* 后序遍历(左右中)
* output:G、H、D、B、I、E、F、C、A
* @param root
*/
public void postOrder(TreeNode root){ if (root == null) {
return;
} else {
postOrder(root.leftChild);
postOrder(root.rightChild);
System.out.println("postOrder data:" + root.getData());
}
}

满二叉树、完全二叉树和二叉查找树、 2-3查找树

1、满二叉树

定义:高度为h,并且由2h-1个结点组成的二叉树,称为满二叉树

2、完全二叉树

定义:一棵二叉树中,只有最下面两层结点的度可以小于2,并且最下层的叶结点集中在靠左的若干位置上,这样的二叉树称为完全二叉树。

特点:叶子结点只能出现在最下层和次下层,且最下层的叶子结点集中在树的左部。显然,一棵满二叉树必定是一棵完全二叉树,而完全二叉树未必是满二叉树。

3、二叉查找树

定义:二叉查找树又被称为二叉搜索树。设x为二叉查找树中的一个结点,x结点包含关键字key,结点x的key值计为key[x]。如果y是x的左子树中的一个结点,则key[y]<=key[x];如果y是x的右子树的一个结点,则key[y]>=key[x]

在二叉查找树种:

(1)若任意结点的左子树不空,则左子树上所有结点的值均小于它的根结点的值。

(2)任意结点的右子树不空,则右子树上所有结点的值均大于它的根结点的值。

(3)任意结点的左、右子树也分别为二叉查找树。

(4)没有键值相等的结点。

二叉查找树BST——Java实现

详细图文说明

https://blog.csdn.net/javazejian/article/details/53727333

2-3查找树

  1. 对于2节点,该节点保存一个key及对应value,以及两个指向左右节点的节点,左节点也是一个2-3节点,左节点所有的值都比该节点的key要小,右节点也是一个2-3节点,所有的值比该节点的key要大。

  2. 对于3节点,该节点保存两个key及对应value,以及三个指向左中右的节点。左节点也是一个2-3节点,所有的值均比两个key中的最小的key还要小;中间节点也是一个2-3节点,中间节点的key值在两个跟节点key值之间;右节点也是一个2-3节点,节点的所有key值比两个key中的最大的key还要大。

平衡二叉树 、 红黑树、替罪羊树、Treap、伸展树

平衡二叉树是一种特殊的二叉搜索树,在按顺序向插入二叉搜索树中插入值,最后会形成一个类似链表形式的树,而我们设计二叉搜索树的初衷,显然是看中了它的查找速度与它的高度成正比,如果每一颗二叉树都像链表一样,那就没什么意思了,所以就设计出来了平衡二叉树,相对于二叉搜索树,平衡二叉树的一个特点就是,在该树中,任意一个节点,它的左右子树的差的绝对值一定小于2。

1.本身首先是一棵二叉搜索树。

2.带有平衡条件:每个结点的左右子树的高度之差的绝对值(平衡因子)最多为1。

也就是说,AVL树,本质上是带了平衡功能的二叉查找树(二叉排序树,二叉搜索树)。

AVL树的查找、插入和删除在平均和最坏情况下都是O(logn)。

如果在AVL树中插入或删除节点后,使得高度之差大于1。此时,AVL树的平衡状态就被破坏,它就不再是一棵平衡二叉树;为了让它重新维持在一个平衡状态,就需要对其进行旋转处理

平衡二叉树的旋转

左-左型:做右旋

右-右型:做左旋

左-右型:先做左旋,后做右旋

右-左型:先做右旋,后做左旋

这里假设结点X是失衡点,它必须重新恢复平衡,由于任意结点的孩子结点最多有两个,而且导致失衡的必要条件是X结点的两棵子树高度差为2(大于1),因此一般只有以下4种情况可能导致X点失去平衡:

① 在结点X的左孩子结点的左子树中插入元素

② 在结点X的左孩子结点的右子树中插入元素

③ 在结点X的右孩子结点的左子树中插入元素

④ 在结点X的右孩子结点的右子树中插入元素

以上4种情况,其中第①情况和第④情况是对称的,可以通过单旋转来解决,而第②种情况和第③情况是对称的,需要双旋转来解决。

左左单旋转(LL)需要右旋转

右右单旋转(RR)进行左旋转

https://blog.csdn.net/javazejian/article/details/53892797

https://www.jb51.net/article/154428.htm

https://blog.csdn.net/cqulun123/article/details/80399371

https://blog.csdn.net/m1179457922/article/details/81745013

https://blog.csdn.net/genius_wolf/article/details/85267253

https://www.jianshu.com/p/4f5eca987990

https://www.cnblogs.com/qm-article/p/9349681.html

https://blog.csdn.net/m0_38036210/article/details/100517125

《剑指offer》

https://www.cnblogs.com/mingyueanyao/p/10322643.html

https://algs4.cs.princeton.edu/33balanced/

http://pages.cs.wisc.edu/~ealexand/cs367/NOTES/AVL-Trees/index.html

https://visualgo.net/en/bst

红黑树

https://www.cs.usfca.edu/~galles/visualization/RedBlack.html

平衡树(AVL)是为了解决 二叉查找树(BST)退化为链表的情况。

红黑树(RBT)是为了解决 平衡树 在删除等操作需要频繁调整的情况。

红黑树5个特征

红黑树是每个节点都带有颜色属性的二叉查找树,颜色或红色或黑色。在二叉查找树强制一般要求以外,对于任何有效的红黑树我们增加了如下的额外要求:

  1. 节点是红色或黑色。

  2. 根节点是黑色。

  3. 每个叶节点(NIL节点,空节点)是黑色的。

  4. 每个红色节点的两个子节点都是黑色。(从每个叶子到根的所有路径上不能有两个连续的红色节点)

  5. 从任一节点到其每个叶子的所有路径都包含相同数目的黑色节点。

红黑树是一种具有红色和黑色链接的平衡查找树,同时满足:

红色节点向左倾斜

一个节点不可能有两个红色链接

整个树完全黑色平衡,即从根节点到所以叶子结点的路径上,黑色链接的个数都相同。

如果我们将红色的连线水平绘制,那么他链接的两个2-node节点就是2-3树中的一个3-node节点了。

红黑树的应用比较广泛,主要是用它来存储有序的数据,它的时间复杂度是O(logn),效率非常之高。

例如,Java集合中的TreeSet和TreeMap,C++ STL中的set、map,以及Linux虚拟内存的管理,都是通过红黑树去实现的。

https://www.cnblogs.com/yangecnu/p/Introduce-Red-Black-Tree.html

https://blog.csdn.net/eson_15/article/details/51144079

https://blog.csdn.net/v_july_v/article/details/6105630

平衡二叉树红黑树两者的区别

1、红黑树并不追求“完全平衡”——它只要求部分地达到平衡要求,降低了对旋转的要求,从而提高了性能。红黑树能够以O(log2 n) 的时间复杂度进行搜索、插入、删除操作。此外,由于它的设计,任何不平衡都会在三次旋转之内解决。当然,还有一些更好的,但实现起来更复杂的数据结构 能够做到一步旋转之内达到平衡,但红黑树能够给我们一个比较“便宜”的解决方案。红黑树的算法时间复杂度和AVL相同,但统计性能比AVL树更高。当然,红黑树并不适应所有应用树的领域。如果数据基本上是静态的,那么让他们待在他们能够插入,并且不影响平衡的地方会具有更好的性能。如果数据完全是静态的,例如,做一个哈希表,性能可能会更好一些。在实际的系统中,例如,需要使用动态规则的防火墙系统,使用红黑树而不是散列表被实践证明具有更好的伸缩性,典型的用途是实现关联数组。

2、AVL树是最先发明的自平衡二叉查 找树。在AVL树中任何节点的两个儿子子树的高度最大差别为一,所以它也被称为高度平衡树。查找、插入和删除在平均和最坏情况下都是O(log n)。增加和删除可能需要通过一次或多次树旋转来重新平衡这个树。

B树、B_树、B+树

B树(B-tree)是一种树状数据结构,它能够存储数据、对其进行排序并允许以O(log n)的时间复杂度运行进行查找、顺序读取、插入和删除的数据结构。B树,概括来说是一个节点可以拥有多于2个子节点的二叉查找树。与自平衡二叉查找树不同,B-树为系统最优化大块数据的读和写操作。B-tree算法减少定位记录时所经历的中间过程,从而加快存取速度。普遍运用在数据库和文件系统。”

定义

B 树可以看作是对2-3查找树的一种扩展,即他允许每个节点有M-1个子节点。

根节点至少有两个子节点

每个节点有M-1个key,并且以升序排列

位于M-1和M key的子节点的值位于M-1 和M key对应的Value之间

其它节点至少有M/2个子节点

https://blog.csdn.net/u012124438/article/details/78109466

https://article.itxueyuan.com/wy3Bon

https://segmentfault.com/a/1190000020416577?utm_source=tag-newest

https://www.iteye.com/blog/uule-2429508

https://www.cnblogs.com/yangecnu/p/Introduce-B-Tree-and-B-Plus-Tree.html

B+树

B+树是对B树的一种变形树,它与B树的差异在于:

有k个子结点的结点必然有k个关键码;

非叶结点仅具有索引作用,跟记录有关的信息均存放在叶结点中。

树的所有叶结点构成一个有序链表,可以按照关键码排序的次序遍历全部记录。

二叉树基本知识

https://blog.csdn.net/qingtian_1993/article/details/80637917

https://segmentfault.com/a/1190000014743964

https://github.com/mcrwayfun/java-data-structure/blob/master/doc/source/tree/树.md

https://blog.csdn.net/m0_38036210/article/category/9225624

树的基本概念以及java实现二叉树的更多相关文章

  1. 数据结构与算法->树->2-3-4树的查找,添加,删除(Java)

    代码: 兵马未动,粮草先行 作者: 传说中的汽水枪 如有错误,请留言指正,欢迎一起探讨. 转载请注明出处. 目录 一. 2-3-4树的定义 二. 2-3-4树数据结构定义 三. 2-3-4树的可以得到 ...

  2. 异常的概念和Java异常体系结构

    一. 异常的概念和Java异常体系结构     异常是程序运行过程中出现的错误.本文主要讲授的是Java语言的异常处理.Java语言的异常处理框架,     是Java语言健壮性的一个重要体现. Ja ...

  3. Java实现二叉树及相关遍历方式

    Java实现二叉树及相关遍历方式 在计算机科学中.二叉树是每一个节点最多有两个子树的树结构.通常子树被称作"左子树"(left subtree)和"右子树"(r ...

  4. 数据结构(5):Java实现二叉树

    二叉树图: package com.test.Sort; import java.util.ArrayList; import java.util.LinkedList; public class B ...

  5. java实现二叉树的Node节点定义手撕8种遍历(一遍过)

    java实现二叉树的Node节点定义手撕8种遍历(一遍过) 用java的思想和程序从最基本的怎么将一个int型的数组变成Node树状结构说起,再到递归前序遍历,递归中序遍历,递归后序遍历,非递归前序遍 ...

  6. JVM 内部原理(五)— 基本概念之 Java 虚拟机官方规范文档,第 7 版

    JVM 内部原理(五)- 基本概念之 Java 虚拟机官方规范文档,第 7 版 介绍 版本:Java SE 7 每位使用 Java 的程序员都知道 Java 字节码在 Java 运行时(JRE - J ...

  7. java创建二叉树并实现非递归中序遍历二叉树

    java创建二叉树并递归遍历二叉树前面已有讲解:http://www.cnblogs.com/lixiaolun/p/4658659.html. 在此基础上添加了非递归中序遍历二叉树: 二叉树类的代码 ...

  8. java实现二叉树查找树

    二叉树(binary)是一种特殊的树.二叉树的每个节点最多只能有2个子节点: 二叉树 由于二叉树的子节点数目确定,所以可以直接采用上图方式在内存中实现.每个节点有一个左子节点(left childre ...

  9. 哈弗曼树的理解和实现(Java)

    哈弗曼树概述 哈弗曼树又称最优树,是一种带权路径长度最短的树,在实际中有广泛的用途.哈弗曼树的定义,涉及路径.路径长度.权等概念.哈弗曼树可以用于哈弗曼编码,用于压缩,用于密码学等. 哈弗曼树的一些定 ...

随机推荐

  1. AXI总线协议

    AXI总线协议 (一).概述 AXI (高性能扩展总线接口,Advanced eXtensible Interface)是ARM AMBA 单片机总线系列中的一个协议,是计划用于高性能.高主频的系统设 ...

  2. Qradar SIEM--查询利器 AQL

    对于 SIEM 平台来说,好用的查询方式非常重要.之前有体验基于 ELK 搭建的平台,在 kibana 上面是可以通过一些 filter 来做一些过滤并且是支持 lucene 的语法,包括一些简单的逻 ...

  3. git工作简要流程

    1.在线上创建新的功能分支,更新到本地: git pull 2.切换分支: git checkout branch-name 3.去代码编辑器开始你的表演 4.添加代码到缓冲区以备提交: git ad ...

  4. 前端开发-css基础入门

    CSS  cascading(层叠) style(样式) sheet(表) css注释 /* 注释内容 */ 快捷键:ctrl ? 引入方式 <!-- 1.行间样式 --> <div ...

  5. MongoDB的使用学习之(六)MongoDB的高级查询之条件操作符

    此文分为两点,主要是在第二点--java 语法,但是按顺序必须先把原生态的语法写出来 (还有一篇文章也是不错的:MongoDB高级查询用法大全(包含MongoDB命令语法和Java语法,其实就是我整理 ...

  6. debian利用snmp监控服务器异常状态

    1.安装snmp apt-get install snmp snmpd 2.配置snmp vi /etc/snmp/snmpd.conf 注释15行 #agentAddress udp:127.0.0 ...

  7. Zabbix--04 自定义模版、web监控

    目录 一.自定义模版 1.创建模版 2.导出模版 3.监控TCP11种状态 3.2.重启zabbix-agent 3.3.测试监控项 4.导入模版文件 5.主机关联模版文件 6.查看最新数据 7.查看 ...

  8. Educational Codeforces Round 55 (Rated for Div. 2) D. Maximum Diameter Graph (构造图)

    D. Maximum Diameter Graph time limit per test2 seconds memory limit per test256 megabytes inputstand ...

  9. [每日一学]apache camel|IBMWebsphere MQ header issue|MQRFH2 |MQSTR

    最近工作中,遇到一个很奇怪的问题: 现象:在camel开发中,通过 IBM Websphere MQ 给assasin 发送xml的message时,会多出<mcd>等这样的header出 ...

  10. jAVA基础 提高文件复制性能之多线程复制文件

    利用IO流中的随机访问文件 RandomAccessFile 和文件通道 FileChanne 复制文件可大大提高文件的读写效率,在此基础上利用多线程复制文件使其性能更优.因线程的个数可根据文件的大小 ...