树的基本概念
定义
概念(什么是树,什么是子树):
树是递归的
*思考题:n个结点有(n-1)条边
基本术语
(祖先结点和子孙结点,双亲结点和孩子结点,结点的度,树的度,分支结点,叶子结点,结点的层次、高度、深度,有序树和无序树,路径,路径长度,森林)
树的性质
1,结点数和度数 节点数=所有的度数之和+1
2,某一层的结点数 i层最大节点数=m^(i-1) 这棵树是一颗m×树
3,总共的结点数 (m^h-1)/m-1
4,结点与高度 给了你一堆结点,给了你树的结构(度数),要你给出该树的最小高度
二叉树的基本概念
定义
概念:空树,左子树,右子树
五种基本形态
*思考题:1,三个结点的二叉树有多少个?
2,二叉树和度为二的有序树的异同?
几种特殊的二叉树
满二叉树 : 定义,性质(编号)
完全二叉树 :定义,性质
二叉排序树 :定义
平衡二叉树 : 定义
二叉树的性质
1、叶子结点和度为二的节点数的关系 n0=n2+1
2、某一层的节点数 2^(k-1)
3、全部的节点数2^h-1
4、完全二叉树的一些性质
5、给你n结点,你给我搭建一棵完全二叉树
二叉树的存储结构
顺序存储
链式存储
二叉树的遍历
递归
先序遍历:
void PreOrder(BiTree T){
if(T!=NULL){
visit(T);
PreOrder(T->lchild);
PreOrder(T->rchild);
}
}
中序,后序可以类推
非递归
算法思想:
1.初始化一个栈,并将根节点及其所有左侧结点一一进栈
2.出栈一个结点,访问它
3.扫描该结点的右孩子,并进栈
4.依次扫描右孩子结点的所有左侧结点并一一进栈
5.反复该操作,直到栈空
中序遍历:
void InOrder2(BiTree T){
InitStack(s); Bitree p = T;
while(p||!IsEmpty(s)){//p非空时
if(p){
Push(s,p);
p=p->Lchild;//扫描根节点的左侧结点并进栈
}
else{
Pop(S,p);visit(p)//出栈一个元素,并访问它
p=p->rchild;//扫描该节点的右孩子并进栈
}
}
}
先序和后序可以类推:
层序遍历:
1.将根结点入队,并访问
2.如果有左子树,入队
3.如果有右子树,入队
4.出队访问
5.直到队列空
void levelOrder(Bitree T){
InitQueue(Q);
BiTree p;
EnQueue(Q,T);
while(!isEmpty(Q)){
DeQueue(Q,p);
visit(p);
if(p->lchird!=NULL)
EnQueue(Q,p->lchilld);
if(p->rchird!=NULL)
EnQueue(Q,p->rchilld);
}
}
线索二叉树:
代码实现:
void InThread(ThreadTree &p,ThreeTree &pre){
if(p!=NULL){
InThread(p->lchild,pre);
if(p->lchild==NULL){
p->lchild=pre;
p->ltag=1;
}
if(pre!=NULL&&pre ->rchild==NULL){
p->rchild=p;
p->rtag=1;
}
pre=p;
InThread(p->lchild,pre);
}
}
树的三种存储结构
双亲表示法:
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
---|---|---|---|---|---|---|---|---|---|---|
data | r | a | b | c | d | e | f | g | h | k |
parent | -1 | 0 | 0 | 0 | 1 | 1 | 3 | 6 | 6 | 6 |
孩子表示法:
孩子兄弟表示法:左指针指向第一个孩子,右指针指向右边第一个兄弟
树,二叉树,森林的转换
树转化为二叉树
森林转化为二叉树
转化后: