相关概念
树的相关概念
1.结点:树中一个独立的单元
2.结点的度:结点拥有的子树数
3.叶子/终端结点:度=0的结点
4.分支结点:度>0的结点(除根结点外,其他分支结点也称为内部结点)
5.树的度:树中所有结点的度的最大值
6.孩子:结点的子树的根,相应的该结点成为孩子的双亲
兄弟:同一个双亲的孩子
7.祖先:从根到该结点所经分支的所有结点
子孙:以某结点为根的子树的任一结点
8.结点层次:从跟开始定义,根为第一层,根的孩子为第二层
堂兄弟:同一层的结点互为堂兄弟
9.数的深度:树中叶子结点所在的最大层次
10.有序树:子树之间存在确定的次序关系。在有序树中最左边的子树的根称为第一个孩子,最右边的树称为最后一个孩子。
否则为无序树。
二叉树的概念
定义:
二叉树是n个结点所构成的集合。它或为空树,或为非空树。对于非空树T:
-
有且仅有一个根结点
-
除根结点外的其余结点分为两个互不相交的子集T1,T2,分别称为T的左子树和右子树,且T1,T2本身也是二叉树。
二叉树性质:
-
二叉树第i层上至多有 2i-1个结点。
-
基于第一条性质,深度为k的二叉树上结点数最多为2k-1个
-
任意一颗二叉树,含有n0个叶子结点,n2个度为2的结点,则有: n0=n2+1
证明: 总结点 n =n0 +n1 +n2
总分支数 B : n = B +1
n = n1 +2*n2 +1
所以得证。
注:二种特殊的二叉树:
满二叉树:指的是深度为k且含有2k-1个结点的二叉树。
特点是每一层上的结点数都是最大结点数。
完全二叉树:如果二叉树中除去最后一层结点为满二叉树,且最后一层的结点一次从左到右分布。
-
具有 n 个结点的完全二叉树的深度为[long2 n] +1
-
若对含 n 个结点的完全二叉树从上到下且从左至右进行 1 至 n 的编号,则对完全二叉树中任意一个编号为 i 的结点:
(1) 若 i=1,则该结点是二叉树的根,无双亲, 否则,编号为 [i/2] 的结点为其双亲结点;
(2) 若 2i>n,则该结点无左孩子,
否则,编号为 2i的结点为其左孩子结点;
(3) 若 2i+1>n,则该结点无右孩子结点,
否则,编号为2i+1 的结点为其右孩子结点。
二叉树创建、遍历
**二叉树链式存储结构:**数据域
指针域:左孩子指针 和 右孩子指针
算法
先序遍历
先序遍历创建二叉树
1.读入字符 ch
2.若ch==0,则该二叉树为空树(T = NULL),若不为0,则执行以下操作:
- 申请一个结点空间T(T = new treeNode)
- 将ch赋值给T->data
- 递归创建T的左子树
- 递归创建T的右子树
调用过程
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UJbNgYyC-1626020917608)(C:\Users\wujia\AppData\Roaming\Typora\typora-user-images\image-20210712002551249.png)]
计算二叉树的深度
若树为空树,返回0;若树非空,利用递归定义,树的深度=左子树和右子树中深度较大者 +1
统计树的结点个数
如果树为空树,结点数返回为0;否则利用递归,返回左子树的结点数+右子树的结点数+1
代码实现
#include <iostream>
using namespace std;
#define elemType int
typedef struct treeNode{
elemType data;
treeNode * lchild;
treeNode * rchild;
} * nodePtr;
void createTree(nodePtr &T){
elemType ch;
cin>> ch;
if(!ch) T = NULL;
else{
T = new treeNode;
T->data = ch;
createTree(T->lchild);
createTree(T->rchild);
}
}
void preTree(nodePtr &T){
if(T){
cout<< T->data ;
preTree(T->lchild);
preTree(T->rchild);
}
}
void midTree(nodePtr &T){
if(T){
preTree(T->lchild);
cout<< T->data ;
preTree(T->rchild);
}
}
void postTree(nodePtr &T){
if(T){
preTree(T->lchild);
preTree(T->rchild);
cout<< T->data ;
}
}
int numOfNode(nodePtr T){
if(!T)
return 0;
return 1 + numOfNode(T->leftChild) + numOfNode(T->rightChild);
};
int depthOfNode(nodePtr T){
if(!T)
return 0;
return depthOfNode(T->leftChild) >= depthOfNode(T->rightChild) ?
depthOfNode(T->leftChild) + 1 : depthOfNode(T->rightChild) + 1;
}
确定一颗二叉树
由二叉树的先序序列和中序序列,或由其后序序列和中序序列均能唯一确定一颗二叉树