树具有的特点有:

(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. 解决Java线程池任务执行完毕后线程回收问题

      转载请注明出处:http://www.cnblogs.com/pengineer/p/5011965.html         对于经常使用第三方框架进行web开发的程序员来说,Java线程池理所 ...

  2. 检验Excel中数据是否与数据库中数据重复

    #region 记录Excel中的重复列 /// <summary> /// 记录Excel中的重复列 /// </summary> /// <param name=&q ...

  3. Jmeter添加压力机

    名词解释: 主控机:启动Jmeter 的机器 负载机:为压力测试提供除主控机之外资源的机器 步骤: 1.先在其他的负载机(另外的电脑)上启动jmeter-server (jmeter-server.b ...

  4. JS事件流、事件监听、事件对象、事件委托

    JS事件流: 01.DOM级别和DOM事件 02.JS事件流:页面中接收事件的顺序 事件冒泡阶段-->处于目标阶段-->事件捕获阶段 (事件捕获总发生在事件冒泡前面) 03.捕获:从外向里 ...

  5. mv - 移动 (改名) 文件

    摘要 mv [选项]... 源文件 目标文件 mv [选项]... 源文件... 目录 mv [选项]... --target-directory=DIRECTORY SOURCE... 描述 改“源 ...

  6. 115-基于TI TMS320DM6467无操作系统Camera Link智能图像分析平台

    基于TI TMS320DM6467无操作系统Camera Link智能图像分析平台 1.板卡概述 该板卡是我公司推出的一款具有高可靠性.效率大化.无操作系统的智能视频处理卡,是机器视觉开发上的选.  ...

  7. Web基础之http协议

    第6章 Web基础之http协议 第6章 Web基础之http协议一.http协议介绍 1.1)什么是超文本 1.2)什么是URL 1.3)什么是超文本传输协议二.访问网站分析三.页面请求信息解析(仅 ...

  8. The Complex Inversion Formula. Bromwich contour.

    网址:http://www.solitaryroad.com/c916.html

  9. socket keepalive 服务端异常断线

    异常断线  客户端检测不到  没有重连

  10. php 强制类型转换

      123 123.01 array("123",123) true false null (string)  "123" "123.01" ...