结构
树是一种非线性的数据结构,是由n(n>=0)个节点组成的集合。
-
如果n=0,是一棵空数
-
如果n>0,树有一个特殊的节点,这个节点没有父节点,被称为根节点(root)
-
除根结点之外的其余数据元素被分为m(m≥0)个互不相交的集合T1,T2,……Tm-1,其中每一个集合Ti(1<=i<=m)本身也是一棵树,被称作原树的子树
-
节点
它包含数据项,和指向其他节点的指针,上图中的树,有11个节点
节点的度
节点所拥有的子树的数量
1.4 叶节点
度为0的节点被成为叶节点, 如上图中的 5 7 8 9 10 11
1.5 分支节点
除叶节点外的节点就是分支节点, 如上图中的 1 2 3 4
1.5 子女节点
若节点x有子树,则这颗子树的根节点就是节点x的子女节点,例如2 3 4 都是1的子女节点
1.6 父节点
若节点x有子女节点,则x为子女节点的父节点,例如 1是 2 3 4 的父节点,2 是 5 6 的父节点
1.7 兄弟节点
同一个父节点的子女节点互称为兄弟, 如 5 和 6 是兄弟节点
1.8 祖先节点
从根节点到该节点所进过分支上的所有节点,如节点5 ,它的祖先节点为 1 2
1.9 子孙节点
某一个节点的子女,以及这些子女的子女都是该节点的子孙节点,如节点2 ,5 6 11 都是它的子孙节点
1.10 节点所在层次
根节点在第一层,它的子女在第二层,以此类推
1.11 树的深度
树中距离根节点最远的节点所处的层次就是树的深度,上图中,树的深度是4
1.12 树的高度
叶节点的高度为1,非叶节点的高度是它的子女节点高度的最大值加1,高度与深度数值相等,但计算方式不一样,上图中树的
1.13 树的度
树中节点的度的最大值,上图中,所有节点的度的最大值是3,树的度就是3
1.14 有序树
树中节点的各棵字树 T1,T2...是有次序的,T1是第1棵子树,T2是第2棵子树
1.15 无序树
树中节点的各棵子树之间的次序不重要,可以互相交换位置
1.16 森林
森林是m(m>=0)棵树的集合
2. 二叉树
二叉树是树的一种特殊情况,每个节点最多有有两个子女,分别称为该节点的左子女和右子女,就是说,在二叉树中,不存在度大于2的节点。二叉树的子树有左右之分,次序不能颠倒,下图是一个二叉树的结构图
2.1 二叉树的性质
- 在二叉树的第i(i>=1)层,最多有2i-1 个节点
- 深度为k(k>=0)的二叉树,最少有k个节点,最多有2k -1 个节点
- 对于一棵非空二叉树,叶节点的数量等于度为2的节点数量加1
2.2 特殊二叉树
2.2.1 满二叉树
深度为k的满二叉树,是有2k-1 个节点的二叉树,每一层都达到了可以容纳的最大数量的节点
2.2.2 完全二叉树
深度为k的完全二叉树,从第1层到第k-1层都是满的,第k层,或是满的或是从右向左连续缺若干个节点
这里我们先实现init_tree,它接收一个表示二叉树的广义表,创建一颗树。
如何用广义表来表达二叉树呢,以广义表 A(B(D,E(G,)),C(,F))# 为例,算法如下
- 广义表的表名放在表前,表示树的根节点,括号中的是根的左右子树
- 每个节点的左右子树用逗号隔开,如果有仅有右子树没有左子树,逗号不省略
- 整个广义表的最后加上特殊符号#表示输入结束
广义表 A(B(D,E(G,)),C(,F))# 所代表的树结构如下图
遍历这个A(B(D,E(G,)),C(,F))# 字符串,来建立一颗二叉树。
遇到左括号的时候,说明前面有一个节点,这个括号里的两个节点都是它的子节点,但是子节点后面还会有子节点,因此,我们需要一个先进后出的数据结构,把前面的节点保存下来,这样,栈顶就是当前要处理的两个节点的父节点。
逗号分隔了左右子树,因此需要一个变量来标识遇到的是左子树还是右子树,假设这个变量为k,遇到左括号的时候,k=1,表示开始识别左子树,遇到逗号,k=2表示开始识别右子树。
遇到右括号,说明一棵子树结束了,那么栈顶的元素正是这棵子树的根节点,执行pop方法出栈。