树
1.遍历二叉树
1.2 二叉树的二叉链表存储表示
typedef struct BiTNode{
telemtype data;//节点数据域
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;//一个:BiTNode的结构体 一个结构体变量:BiTree
1.3中序遍历的递归算法
void InorderTraverse(BiTree T){ //中序遍历
{ if(T){ //非空
InorderTraverse(T->lchild); //访问左孩子,传给左孩子后此时左孩子相当于T
printf("%d",T->data);
InorderTraverse(T->rchild);
}
}
1.3中序遍历的非递归算法
思路:
1.初始化一个空栈S,指针p指向根节点。
2.申请一个节点空间q,用来存放栈顶弹出的元素。
3.当p非空或栈非空时执行以下操作。1.如果p非空,根指针进栈,遍历左子数(
将p进栈,p指向该节点的左孩子
)
2.如果p为空,访问根节点(输出根节点),遍历右子数(弹出栈顶元素,将p指向该节点的右孩子)
//中序遍历非递归:栈的实现
void Inordertraverse(BiTree T){
InitStack(S),p=T;
q=new BiTNode;
while(p || !StackEmpty(S))
{
if(p){
push(S,p);//压栈
p=p->lchild;//访问左孩子
}
else
{
pop(S,q);//出栈
cout<<q-data;
p=q->rchild;//访问右孩子
}
}
}
如图中:当访问到a时,将a(*的左子树)压栈,然后访问a的左孩子,但是为空,则将a出栈。然后访问b(*的右子数)
q时刻指向栈顶元素:将a弹出后,则q指向*,然后输出*,再访问右孩子。
1.4先序遍历的顺序建立二叉链表
思路:
1.扫描字符,读入字符ch
2.如果ch是一个“#”字符,则表明该二叉树为空树,即T为NULL,否则执行以下操作
- 申请一个节点空间T
- 将ch’赋给T->data
- 递归创建T的左子树
- 递归创建T的右子树
void CreatBiTree(BiTree &T){
cin>>ch;
if(ch=="#") T=NULL;
else{
if(!(T=(BiTNode*)malloc(sizeof(BiTNode))))//如果T节点没有空间,则生成空间
T=new BiTNode;
T->data=ch;//生成根节点
CreatBiTree(T->lchild);//创建右子树
CreatBiTree(T->rchild);//创建右子树
}
}
1.5 复制二叉树
思路
如果是空树,递归结束,
否则
执行以下操作
- 申请一个新节点空间,复制根节点
递归复制左子树
递归复制右子树
//复制二叉树
int Copy(BiTree T,BiTree &NewT){//复制树传地址
if(T==NULL){ //如果是空树返回0
NewT=NULL;
return 0;
}
else{
NewT=new BiTNode; NewT->data=T->data;
Copy(T->lchild,NewT->lchild);
//如图中,当赋值A后,执行下面的Copy函数(
//此时T->lchild就相当于T,然后复制树就传地址,为地址分配空间)
Copy(T->rchild,NewT->rchild);
}
}
1.6 计算二叉树的深度
思路
如果是空树,则深度为0,否则
- 递归计算左子树深度为m
- 递归计算右子树深度记为n
二叉树深度为m与n的较大者加1
int Depth(BiTree T){
if(T==NULL) return 0;
else{
m=Depth(T->lchild);
n=Depth(T->rchild);
if(m>n) return (m+1);
else return (n+1);
}
}
根据图片举例:当C为根节点时,递归调用m=Depth(T->lchild)
,但此时C的左孩子为NULL,则直接返回0,然后继续递归调用n=Depth(T->rchild)
,此时也跟m一样,所以此时C为1。而C也是b的左孩子,则根据这种思路,可以求出b的右孩子d的深度为2.
1.7计算二叉树节点总数
- 如果为空树,则节点个数为0
- 否则,节点个数为左子树的节点个数
+
右子树的节点个数再+
1(1表示根节点)
//二叉树的节点数
int NodeCount(BiTree T){
if(T==NULL)
return 0;
else
return NodeCount(T->lchild)+NodeCount(T->rchild)+1;
}
1.8计算二叉树叶子节点数
- 如果是空树,则叶子节点个数为0
- 否则,为左子树的叶子节点个数+右子树的叶子节点个数
int LeafCount(BiTree T){
if(T==NULL)
return 0;
if(T->child==NULL&&T->rchild==NULL)
return 1;
else
return LeafCount(T->lchild)+LeafCount(T->rchild);
}
2.线索二叉树
2.1定义
利用二叉链表中的空指针域:
- 某个节点的左孩子为空,则将空的左孩子指针域改为
指向其前驱
- 某个节点的右孩子为空,则将空的右孩子指针域改为
指向其后继
—这种
改变指向的指针
称为“线索
”
对二叉树按某种次序使其变为线索二叉树的过程叫线索化
为区分lchild和rchild指针:对二叉链表中
每个节点新增两个标志域
ltag 和 rtag,并约定: