引言

对于大量的输入数据,链表的线性访问时间太慢,不宜使用。本篇讨论一种简单的数据结构——树,它大部分操作的运行时间平均为O(logN)O(logN)O(logN)。数据结构中有很多树的结构,其中包括二叉树、二叉搜索树、2-3树、红黑树等等。

树和森林的区别

基本概念

树(tree) 是一些节点的集合。

该集合可以是空集,若不是空集,则树由称为根(root) r 的节点以及0个或多个非空的子树组成。

每颗子树的根就做根r儿子(child),而r是每颗子树的根的父亲。


上图中,A是根,节点F有一个父亲A并且有儿子K、L和M。每个节点可以有零个或任意个儿子。没有儿子的节点称为叶子节点(leaf)

上图中的B、C、H等是叶子节点。

具有相同父亲的节点称为兄弟(siblings),因此B、C、D、E、F、G都是兄弟。这种定义和家谱很像,类似地,我们可以得到祖父孙子的定义。J是A的孙子,A是I的祖父。

从节点n1n_1n1​到nkn_knk​的**路径(path)**定义为节点n1,n2,...,nkn_1,n_2,...,n_kn1​,n2​,...,nk​的一个序列。

这条路径的 长(length) 是为该路径上的边的条数,即k−1k-1k−1。

从每一个节点到它自己有一条长为0的路径。注意,在一颗树中从根到每个节点恰好存在一条路径。

对任意节点nin_ini​的 深度(depth) 为从根到nin_ini​的唯一的路径的长。因此,根的深度为0。

nin_ini​的 高(height) 是从nin_ini​到叶子节点的最长路径的长。因此所有的叶子节点(树叶)高都是0.
一棵树的高等于它的根的高。

对于上文中那颗树,E的深度为1(A-E)而高为2(E-J-Q)。该树的高为3。一棵树的深度等于它的最深的树叶的深度;该深度总是等于这棵树的高。

树这种数据结构有广泛的应用,比如操作系统中用到了红黑树,数据库用到了B+树,编译器用到了语法树。下面用Java来实现各种常见的树。

二叉树

二叉树(binary tree) 是一颗每个节点都不能多于两个孩子(儿子)的树。通常叫它的儿子为左孩子和右孩子(或左子树和右子树)。

二叉树的性质

  • 在非空二叉树中,第i层的节点总数不超过2i−12^{i-1}2i−1,i>=1
  • 深度为h的二叉树最多有2h−12^h - 12h−1个节点
  • 对于任何一颗二叉树,如果其叶子节点数位n0n_0n0​,度为2(同时有两个孩子节点)的节点数为n2n_2n2​,则n0=n2+1n_0 = n_2 + 1n0​=n2​+1
  • 具有n个节点的完全二叉树的深度为log(n+1)log(n+1)log(n+1)
  • 给定n个节点,能构成h(n)种不同的二叉树,其中h(n)为卡特兰数的第n项,h(n)=C(2n,n)n+1h(n) = \frac{C(2n, n)}{n+1}h(n)=n+1C(2n,n)​

满二叉树:除最后一层无任何子节点外,每一层上的所有节点都有两个子节点。

满二叉树的性质

  1. 一颗树深度为h,最大层数为k,深度与最大层数相同,k=h
  2. 叶子数为2h2^h2h
  3. 第k层的节点数是:2k−12^{k-1}2k−1
  4. 总节点数是:2k−12^k-12k−1,且总节点数一定是奇数

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

我们定义通用二叉树接口:

public interface BinaryTree<E> {void insert(E x);void remove(E x);boolean contains(E x);boolean isEmpty();void makeEmpty();void printTree();
}

二叉查找树

见图解二叉查找树

实现好了二叉查找树后,我们利用它来学习二叉树的遍历

二叉查找树的查询效率很依赖于树的深度。


若生成的二叉查找树像这样,其实它就退化为链表。下面介绍一种能自动平衡左右节点的二叉查找树。

AVL树

AVL树通常被称为平衡二叉(搜索)树。

见图解AVL树

AVL树虽然能够自动平衡,但是它有如下显著的缺点:

  • 插入/删除后的旋转,成本不低
  • 删除操作,最坏情况下需要Ω(logN)\Omega(logN)Ω(logN)次旋转

伸展树

伸展树是基于AVL树的,但它并没有AVL的平衡要求,任意节点的左右子树可以相差任意深度。与二叉搜索树类似,伸展树的单次搜索也可能需要n次操作。但伸展树可以保证,m次的连续搜索操作的复杂度为mlog(n)的量级,而不是mn量级。

实现见图解伸展树

B树系列

B-树

B树也称B-树,它是一颗平衡的多路搜索树。我们描述一颗B树时需要指定它的阶数,阶数表示一个节点最多有多少个孩子节点,一般用字母m表示阶数。当m取2时,就是我们常见的二叉搜索树。

有时也称M路B树,即有M个分支的B树

多级存储系统中使用B-树,可针对外部查找,大大减少I/O次数。


可以看到,B树是一颗矮胖的平衡多叉树。
详细图解与Java代码实现见图解B-树

红黑树

敬请期待

数据结构——树的概述相关推荐

  1. JAVA核心知识点之 数据结构:总结概述

    数据结构:总结概述,持续更新 1.1. 栈(stack) 1.2. 队列(queue) 1.3. 链表(Link) 1.4. 散列表(Hash Table) 1.5. 排序二叉树 1.5.1. 插入操 ...

  2. 【自学笔记】尚硅谷数据结构与算法Chapter 1 数据结构与算法概述

    Chapter 1 数据结构与算法概述 文章目录 Chapter 1 数据结构与算法概述 1.1.1 数据结构和算法的关系 1.2.1 线性结构 1.2.2 非线性结构 尚硅谷数据结构B站学习视频地址 ...

  3. python tree结构_Python入门篇-数据结构树(tree)篇

    Python入门篇-数据结构树(tree)篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.树概述 1>.树的概念 非线性结构,每个元素可以有多个前躯和后继 树是n(n& ...

  4. 嵌入式团队培训_数据结构和算法概述

    嵌入式团队培训_数据结构与算法概述 要求:理解并记忆即可,会求解算法的时间复杂度 一:数据结构 1.逻辑结构: 2.物理结构 3.抽象数据类型 二:算法 1.算法的五个基本特征: 2.算法设计的要求 ...

  5. js 数组 实现 完全树_算法和数据结构 | 树状数组(Binary Indexed Tree)

    本文来源于力扣圈子,作者:胡小旭.点击查看原文 力扣​leetcode-cn.com 树状数组或二叉索引树(英语:Binary Indexed Tree),又以其发明者命名为 Fenwick 树.其初 ...

  6. [转]C#与数据结构--树论--平衡二叉树(AVL Tree)

    C#与数据结构--树论--平衡二叉树(AVL Tree) http://www.cnblogs.com/abatei/archive/2008/11/17/1335031.html 介绍 我们知道在二 ...

  7. 数据结构—树与二叉树

    总第119篇 前言 之前谈到的线性表.栈和队列都是一对一的数据结构,但是现实中也存在很多一对多的数据结构,这篇要写的就是一种一对多的数据结构---树.全文分为如下几部分: 树的一些基本概念 树的存储结 ...

  8. 数据结构树二叉树计算节点_查找二叉树中叶节点的数量 数据结构

    数据结构树二叉树计算节点 Algorithm: 算法: One of the popular traversal techniques to solve this kind of problems i ...

  9. 数据结构——树状数组

    我们今天来讲一个应用比较广泛的数据结构--树状数组 它可以在O(nlogn)的复杂度下进行单点修改区间查询,下面我会分成三个模块对树状数组进行详细的解说,分别是树状数组基本操作.树状数组区间修改单点查 ...

  10. 剑指offer(C++)-JZ78:把二叉树打印成多行(数据结构-树)

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 给定一个节点数为 n 二叉树,要求从上到下按层打印二叉树的 val 值,同一层结点从 ...

最新文章

  1. 计算机的五大主要应用领域是电大,电大计算机应用基础考答案
  2. 杰森·保罗:使VR与人眼相匹配还需20年!
  3. python学习日常-编码与字符串格式化
  4. cgo的几种使用方式
  5. 【SSL】使用Keytool工具生成证书及签名完整步骤
  6. java正则表达式性能_译:Java 中的正则表达式性能概述
  7. 精读《你不知道的javascript》中卷
  8. 清空linux当前页面内容,linux文档整理
  9. LINUX让环境变量立即生效的方法
  10. linux语音识别_linux语音识别 arm_linux 语音识别引擎 - 云+社区 - 腾讯云
  11. 搜索引擎网页排序算法
  12. iptv管理系统php制作,云水日记-双子星IPTV管理系统搭建教程
  13. 乞丐的一句话,感动中国13亿人。
  14. Flink编程中遇到”scala.tools.reflect.ToolBoxError: reflective compilation has failed“的解决方法
  15. 922175-70-0,Galacto-RGD,RGDfK(SAA),νβ3表达成像示踪剂
  16. 密码学基础(二)单表---置换密码 凯撒密码 棋盘密码 乘法密码 仿射密码 多表---vigenere方阵
  17. html5金花,HTML5 2D Graphic 实现五朵金花版型设计
  18. excel如何数据汇总之多工作簿
  19. Neo4j笔记(二)Cypher(6)UNWIND和FOREACH
  20. bzoj2144 [2011集训队出题] 跳跳棋 倍增 lca

热门文章

  1. 生态功能区划方法之一:生态敏感性分析法
  2. SQL 语句语法简介(一)
  3. 洛谷P1880 石子合并 区间动归
  4. DB2数据库用 With语句分隔字符
  5. 收集一些关于视频文件格式以及编码计算的一些知识
  6. 去除TCP/IP筛选
  7. CSblog的学习记录
  8. STM32CubeMX 配置STM32F407 实现HAL库延时微妙方案
  9. Source Insight 4.0常见问题和常用配置
  10. C#代码执行中等待10秒