树具有的特点有:

(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

递归实现二叉树的遍历

前序遍历

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

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)没有键值相等的结点。

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

对于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://www.cs.usfca.edu/~galles/visualization/RedBlack.html

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

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

红黑树5个特征

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

节点是红色或黑色。

根节点是黑色。

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

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

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

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

红色节点向左倾斜

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

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

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

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

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

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

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个子节点

B+树

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

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

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

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

java二叉树是什么_树的基本概念以及java实现二叉树相关推荐

  1. 树的基本概念以及java实现二叉树(二)

    前言 本文是我在学习了树后作的总结文章,接上篇文章,本节大致可以总结为: 二叉树的遍历与实现(递归和非递归) 获取二叉树的高度和度 创建一棵二叉树 其他应用(层序遍历,复制二叉树,判断二叉树是否相等) ...

  2. 树的基本概念以及java实现二叉树(一)

    前言 作为一个程序员,要了解最基本的数据结构的.本文是我在学习了树后作的总结文章,本节大致可以总结为: 什么是树 树的基本性质(专有名词) 什么是二叉树 二叉树的基本性质 二叉树的存储结构 文章传送门 ...

  3. JAVA基础再回首(一)——基本概念、JAVA开发工具、JAVA基本语法

    JAVA基础再回首(一)--基本概念.JAVA开发工具.JAVA基本语法 学了java,做了android应用开发,现在回想起来,真的是一路坎坷..我在上章博客中提到了我以后的几个学习计划和目标就是把 ...

  4. 中秋节图案 用java代码打出来_这个中秋,我用 Java 画了一个月饼!

    栈长代表微信公众号 "Java技术栈" 祝所有粉丝中秋佳节快乐! 为了用一种特殊的方式表达我的心意,去年中秋节,我写了这篇文章: 没错,去年一天,我学了 20 种编程语言,刺激.. ...

  5. java生成pdf图表_开发员指南:使用Java图表转换为PDF/JPG等图像

    Aspose.Cells for JavaExcel电子表格处理API,它允许Java开发人员在自己的Java应用程序中嵌入可读取.写入和操作Excel电子表格的能力,而无需依赖Microsoft E ...

  6. java泛型 简书_一文带你认识Java泛型基础

    Java泛型基础 1. 认识泛型 泛型是在JDK1.5之后增加的新功能. 泛型可以解决数据的安全性问题, 主要的原理是在类声明的时候通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型. ...

  7. mac上java文件如何编译_如何在Mac上用Java编译和运行程序?

    小编典典 在Mac OSX或任何主要操作系统上编译和运行Java应用程序非常容易.Apple随OSX一起提供了一个功能齐全的Java运行时和开发环境,因此您要做的就是编写Java程序并使用内置工具来编 ...

  8. java编程最新图书_清华大学出版社-图书详情-《Java程序设计》

    前言 Java是一种完全面向对象的程序设计语言,具有卓越的通用性.高效性.平台移植性和安全性,得到广泛的应用.在全球云计算和移动互联网产业高速发展的环境下,Java具备显著的优势和广阔前景.本书以Ja ...

  9. java自动推断类型_推断:Facebook的新Java静态分析工具

    java自动推断类型 如何使用Facebook的Infer改善Java开发工作流程? 如果您与技术话题保持同步(如果您正在阅读此博客,我想您会这样做),那么您可能听说过Facebook 刚刚向公众发布 ...

最新文章

  1. 教你用Python进行自然语言处理(附代码)
  2. 未来智能制造就是跨界大数据
  3. 无法relay信件处理一例
  4. C# 去除文件和文件夹的只读属性
  5. 【Java文件操作】txt文件的创建
  6. 常见的几款JVM监控工具
  7. ModelMap和ModelAndView的作用
  8. docker运行yyets_使用Docker镜像
  9. 聚焦大数据与智能时代:2016中国大数据应用大会将于7月举行
  10. 【信号与系统】信号频谱和测量之汉明窗
  11. FTL(闪存转换层)简单介绍
  12. 用python画图的好处_用Python绘图,感受编程之美
  13. Otsu最大类间方差法
  14. android 获取邮箱账号,android获取google邮箱
  15. 当跳槽遇到互联网公司裁员寒潮,该如何应对?
  16. 用lua随手写的扑克发牌方案
  17. Containerd镜像lazy-pulling「详细解读 」
  18. xshell6和xftp6安装后无法打开提示升级到最新版本
  19. 企业数字化转型:聊聊数据思维!
  20. 百度地图API_BMap接口的使用形式

热门文章

  1. 软件测试面试英文自我介绍,软件测试工程师面试英文自我介绍范文.doc
  2. C语言程序设计--火车订票系统
  3. layaair引擎做的一个三消游戏
  4. Java泛型-泛型作用+泛型在各种数据结构中的使用+自定义泛型
  5. 驰骋工作流Jeesite4-jflow版本安装数据库的步骤
  6. C# 构造函数和析构函数
  7. ipv4和ipv6显示服务器无响应,将IPv4客户端连接到IPv6服务器:连接被拒绝
  8. nginx的域名转发
  9. 一篇讲解傅里叶分析很幽默透彻的文章
  10. 初次使用git配置以及git如何使用ssh密钥(将ssh密钥添加到github)