第7章树和二叉树:二叉树遍历算法的应用
1. 创建二叉树的存储结构——二叉链表
为简化问题,设二叉树中结点的元素均为一个单字符。
假设按先序遍历的顺序建立二叉链表,T 为指向根结点的指针,对于给定的一个字符序列,依次读入字符,从根结点开始,递归创建二叉树。
【算法步骤】
- 扫描字符序列,读入字符
ch。 - 如果
ch是一个 “#” 字符,则表明该二叉树为空树,即T为NULL;否则执行以下操作:- 申请一个结点空间
T; - 将
ch赋给T->data; - 递归创建
T的左子树; - 递归创建
T的右子树。
- 申请一个结点空间
【算法描述】
//二叉链表
typedef struct BiTNode{TElemType data; //结点数据域struct BiTNode *lchild, *rchild; //左右孩子指针
}BiTNode, *BiTree;//按先序次序输入二叉树中结点的值(一个字符),
//创建二叉链表表示的二叉树 T
void CreateBiTree(BiTree &T){cin>>ch;if(ch == '#') {T = NULL; //递归结束,建空树} else { //递归创建二叉树T = new BiTNode; //生成根结点T->data = ch; //根结点数据域置为 chCreateBiTree(T->lchild); //递归创建左子树CreateBiTree(T->rchild); //递归创建右子树}
}
2. 复制二叉树
复制二叉树就是利用已有的一棵二叉树复制得到另外一棵与其完全相同的二叉树。
根据二叉树的特点,复制步骤如下:
- 若二叉树不空,则首先复制根结点,相当于二叉树先序遍历算法中访问根结点的语句;
- 然后分别复制二叉树根结点的左子树和右子树,这相当于先序遍历中递归遍历左子树和右子树的语句。
因此,复制函数的实现与二叉树先序遍历的实现非常类似。
【算法步骤】
如果是空树,递归结束,否则执行以下操作:
-
申请一个新结点空间,复制根结点;
-
递归复制左子树;
-
递归复制右子树。
【算法描述】
void Copy(BiTree T, BiTree &NewT){//复制一棵和 T 完全相同的二叉树if(T = NULL){//如果是空树,递归结束NewT = NULL;return;}else{NewT = new BiTNode;NewT->data = T->data; //复制根结点Copy(T->lchild, NewT->lchild); //递归复制左子树Copy(T->rchild, NewT->rchild); //递归复制右子树}
}
3. 计算二叉树的深度
二叉树的深度为树中结点的最大层次,即左右子树深度的较大者加 1。
【算法步骤】
如果是空树,递归结束,深度为 0,否则执行一下操作:
- 递归计算左子树的深度,记为 mmm ;
- 递归计算右子树的深度,记为 nnn ;
- 如果 m>nm\gt nm>n ,二叉树的深度为 m+1m+1m+1 ,否则为 n+1n+1n+1 。
【算法描述】
int Depth(BiTree T){//计算二叉树 T 的深度if(T == NULL){return 0; //空树深度为0,递归结束}else{m = Depth(T->lchild); //递归计算左子树的深度 mn = Depth(T->rchild); //递归计算右子树的深度 nif(m > n) return (m + 1); //二叉树深度是 m 与 n 中较大者加 1else return (n+1);}
}
计算二叉树的深度是在后序遍历二叉树的基础上进行的运算。
4. 统计二叉树中结点的个数
【算法描述】
int NodeCount(BiTree T){//统计二叉树 T 中结点的个数if(T == NULL){return 0; //空树,结点个数为 0,递归结束}else{//结点个数为左右子树结点个数相加,再加上根结点个数return NodeCount(T->lchild) + NodeCount(T->rchild) + 1;}
}
5. 统计二叉树中不同度数的结点数量
统计二叉树中度分别是 0,1,2 的结点数量。
【算法描述】
//定义容纳结点数量的结构体
typedef struct{int n0; //度为 0 的结点数量int n1; //度为 1 的结点数量int n2; //度为 2 的结点数量
}NodeDegrees;void countNodeDegrees(BiTree T, NodeDegrees *count){if(T == NULL){ //空树,没有结点return;}//递归统计左右子树的结点countNodeDegrees(T->lchild, count);countNodeDegrees(T->rchild, count);//确定当前结点的度并统计数量if(T->lchild == NULL && T->rchild == NULL){//没有孩子,度为 0count->n0++;} else if(T->lchild != NULL && T->rchild !=NULL){//有左孩子且有右孩子,度为 2count->n2++;} else{//度为 1count->n1++;}
}
