树和二叉树
Posted xwolf
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树和二叉树相关的知识,希望对你有一定的参考价值。
01 树
在计算机科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合。它是由n(n>0)个有限节点组成一个具有层次关系的集合。把它叫做“树”是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。它具有以下的特点:
1. 每个节点都只有有限个子节点或无子节点;
2. 没有父节点的节点称为根节点;
3. 每一个非根节点有且只有一个父节点;
4. 除了根节点外,每个子节点可以分为多个不相交的子树;
5. 树里面没有环路(cycle)。
树的基本术语
基本术语以上图为例来说明。
结点:
6,1,20,43等都是结点。结点不仅包含数据元素,而且包含指向子树的分支。以上图所示,6结点不仅包含数据元素6,还包含3个指向子树的指针。
结点的度:
结点拥有的子树的个数或者分支的个数。例如 6结点有3棵子树,所以3结点的度为3。
树的度:
树中各结点的度的最大值。例如 结点的度的最大值为3(6,43结点),所以树的度为3。
叶子结点:
又叫做终端结点。指度为0的结点。例如5,23,29,8,32,10,0都是叶子结点。
非终端结点:
又叫做分支结点。指度不为0的结点。例如 6,1,20,43,9,7都是非终端结点。
孩子:
结点的子树的根。如 6结点的孩子为1,20,43。
双亲:
与孩子的定义对应。如 1,20,43结点的双亲为6。
兄弟:
同一个双亲的孩子之间互为兄弟。如 1,20,43互为兄弟。
堂兄弟:
双亲在同一层的结点互为堂兄弟。如 7和8互为堂兄弟。
祖先:
从根到某结点的路径上的所有结点,都是该结点的祖先。例如 29结点的祖先是6,1,9。因为从6结点到29结点的路径为6-1-9-29。
子孙:
以某结点为根的子树中的所有结点,都是该结点的子孙。例如 43结点的子孙为7,10,0,32。
层次:
从根开始,根为第一层。根的孩子为第二层,根的孩子的孩子为第三层...
树的高度(深度):
树中结点的最大层次。如图中树的最大层次为4,所以高度为4。
结点的深度和高度:
-
结点的深度是从根节点到该节点路径上的结点个数。
-
从某结点向下走可能到达多个叶子结点,对应了多条通往这些叶子结点的路径,其中最长的那条路径长度即为该结点在树中的高度。
-
根结点的高度为树的高度。
有序树:
树中结点的子树从左到右是有次序的,不能交换,这样的树叫做有序树。
无序树:
树中结点的子树没有顺序,可以任意交换,这样的树叫做无序树。
丰满树:
丰满树即理想平衡树,要求除最底层外,其他层都是满的。
森林:
若干棵互不相交的树的集合。例如 将图中的根节点6去掉,剩下的三棵子树构成一个森林。
树的存储结构
顺序存储结构
树的顺序存储结构中最简单直观的就是用一维数组表示的双亲存储结构。如下图所示:
用char[]来存储树的双亲关系,将对应的树的结点的内容映射为数组的下标,图中直接用字符表示。内容就是该结点的双亲结点。
链式存储结构
这里简单介绍一种孩子兄弟表示法。
以上图的树为例来说明。
看懂图就明白了这种链式存储的方法。
02 二叉树
在理解了树的概念后,二叉树的定义就很好理解了。在树的概念的定义上加上以下两个限制:
-
每个结点最多只有两棵子树,即二叉树中结点的度只能为0,1,2。
-
子树有左右顺序之分,不能颠倒。
根据二叉树的定义,二叉树共有5种形态:
-
空二叉树。(图a)
-
只有一个结点(根节点)。(图b)
-
只有左子树。(图c)
-
只有右子树。(图d)
-
既有左子树,又有右子树。(图e)
满二叉树
在一棵二叉树中,如果所有分支结点都存在左子树和右子树,并且所有叶子都在同一层上,这样的二叉树称为满二叉树。
满二叉树具有如下特点:
-
叶子只能出现在最下一层
-
非叶子结点的度一定是2
-
同样深度的二叉树中,满二叉树的结点个数最多,叶子数最多。
完全二叉树
若设二叉树的高度为h,除第 h 层外,其它各层 (1~h-1) 的结点数都达到最大个数,第h层有叶子结点,并且叶子结点都是从左到右依次排布,这就是完全二叉树。
完全二叉树的特点:
-
叶子结点只能出现在最下两层。
-
最下层叶子在左部并且连续
-
同样结点数的二叉树,完全二叉树的深度最小。
主要性质
-
在二叉树的第i层上至多有 2^(i-1) 个结点(i>=1)。
-
深度为k的二叉树至多有 2^k - 1个结点(k>=1)。
-
具有n (n>=1)个结点的完全二叉树的深度为「log2n」+ 1 ( log2n表示以2为底n的对数,「x」表示不大于x的最大整数) 。
-
如果对一棵有n个结点的完全二叉树的结点按层序编号(从第一层到第「log2n」+ 1层,每层从左到右),对任一结点i(1≤i≤n)有:
-
若i=1,则结点i是二叉树的根,无双亲;如 i>1,则其双亲是结点「i/2」。
-
如2i>n,则结点i无左孩子(结点i为叶子结点);否则其左孩子是结点2i。
-
若2i+1>n,则结点i无右孩子;否则其右孩子是结点2i+1。
5. 给定n个结点,能构成h(n)种不同的二叉树,
则
6. 非空二叉树上叶子结点数等于双分支节点数 加1。
存储结构
顺序存储结构
用一维数组来表示二叉树。将层序结点存储数组中。
链式存储结构
这一张图说明问题,不做过多的解释。
遍历算法
所谓遍历(Traversal)是指沿着某条搜索路线,依次对树中每个结点均做一次且仅做一次访问。访问结点所做的操作依赖于具体的应用问 题。 遍历是二叉树上最重要的运算之一,是二叉树上进行其它运算之基础。本文介绍一下四种遍历算法:
-
前序遍历
前序遍历首先访问根结点然后遍历左子树,最后遍历右子树。在遍历左、右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树。
若二叉树为空则结束返回,否则:
-
访问根结点。
-
递归遍历左子树。
-
递归遍历右子树。
需要注意的是:遍历左右子树时仍然采用前序遍历方法。
-
中序遍历
中序遍历首先遍历左子树再访问根节点,再遍历右子树。
若二叉树为空则结束返回,否则:
-
递归遍历左子树。
-
访问根结点。
-
递归遍历右子树 。
-
后序遍历
后序遍历首先遍历右子树,再遍历左子树,再访问根节点。
若二叉树为空则结束返回,否则:
-
递归遍历右子树。
-
递归遍历左子树 。
-
访问根结点。
-
层序遍历
自上而下,从左到右逐层访问各结点。
本文到此结束,主要介绍了树和二叉树的基本概念和遍历方法等。本文更像一篇论述文,没有涉及实际的代码实践。有需要的同学可对应编码实战。
欢迎关注微信公众号。
以上是关于树和二叉树的主要内容,如果未能解决你的问题,请参考以下文章