基本操作如下:
1、输出先序遍历的结果
2、输出中序遍历的结果
3、输出后序遍历的结果
4、计算结点个数
5、计算叶结点个数
6、统计二叉树的度为1的结点个数
7、交换左右子树
先序遍历的递归算法:
void PreOrderTraverse(BiTree T){ //先序遍历
//先序遍历二叉树T的递归算法
if(T){
cout << T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
以下图的树为例,先序遍历即 根左右 ,所以从根开始看 即A 将其输出,然之后看A的左子树,即B后面的一串,全都是A的左子树,在左子树里继续 “根左右” 循环,这个过程叫做递归。看B 其是根,将其输出,然后看B的左子树,发现左子树为空,那就看右子树,右子树不为空,将其输出,接着看右子树的左子树,为空。右子树的右子树也为空,那么就返回到A的右子树位置,接着根左右,A的右子树是C,C即没有左子树也没有右子树,那么整棵树就遍历完了。所以遍历的结果就为 ABDC。
完整代码如下:
#include<stdio.h>
#include<malloc.h>
#include<iostream>
using namespace std;
typedef struct BiNode{ //二叉链表定义
char data;
struct BiNode *lchild,*rchild;
}BiTNode,*BiTree;
//用算法5.3 先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T){
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else{
T=new BiTNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
void InOrderTraverse(BiTree T){ //中序遍历
//中序遍历二叉树T的递归算法
if(T){
InOrderTraverse(T->lchild);
cout << T->data;
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T){ //后序遍历
//后序遍历二叉树T的递归算法
if(T){
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
cout << T->data;
}
}
void PreOrderTraverse(BiTree T){ //先序遍历
//先序遍历二叉树T的递归算法
if(T){
cout << T->data;
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
int Depth(BiTree T) //计算二叉树的深度
{
int m,n;
if(T == NULL ) return 0; //如果是空树,深度为0,递归结束
else
{
m=Depth(T->lchild); //递归计算左子树的深度记为m
n=Depth(T->rchild); //递归计算右子树的深度记为n
if(m>n) return(m+1); //二叉树的深度为m 与n的较大者加1
else return (n+1);
}
}
int NodeCount(BiTree T) //统计二叉树中结点的个数
{
if(T==NULL) return 0; // 如果是空树,则结点个数为0,递归结束
else return NodeCount(T->lchild)+ NodeCount(T->rchild) +1;
//否则结点个数为左子树的结点个数+右子树的结点个数+1
}
int LeafCount(BiTree T){ //计算叶子结点个数
if(T==NULL)
return 0;
if(T->lchild==NULL&&T->rchild==NULL)
return 1;
else return LeafCount(T->lchild)+LeafCount(T->rchild);
}
int NodeNumber_1(BiTree T) //统计二叉树的度为1的结点个数
{
int i=0;
if(T)
{
if((T->lchild==NULL&&T->rchild!=NULL)||(T->lchild!=NULL&&T->rchild==NULL))
{
i=1+NodeNumber_1(T->lchild)+NodeNumber_1(T->rchild);
}
else
{
i=NodeNumber_1(T->lchild)+NodeNumber_1(T->rchild);
}
}
}
void exchange(BiTree T,BiTree &NewT) // 交换左右子树
{
if(T==NULL)
{
NewT=NULL;
return ;
}
else
{
NewT=(BiTNode *)malloc(sizeof(BiTNode));
NewT->data=T->data;
exchange(T->lchild,NewT->rchild); // 复制原树的左子树给新树的右子树
exchange(T->rchild,NewT->lchild); // 复制原树的右子树给新树的左子树
}
}
int main(){
BiTree tree,NewTree;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
cout<<"先序遍历的结果为:";
PreOrderTraverse(tree);
cout<<"\n";
cout<<"中序遍历的结果为:";
InOrderTraverse(tree);
cout<<"\n";
cout<<"后序遍历的结果为:";
PostOrderTraverse(tree);
cout<<"\n";
cout<<"树的深度为:"<<Depth(tree)<<endl;
cout<<"结点个数为:"<<NodeCount(tree)<<endl;
cout<<"叶子结点总数:"<<LeafCount(tree)<<endl;
cout<<"度为1的结点个数 :"<<NodeNumber_1(tree)<<endl;
cout<<"交换左右子树-->\n";
exchange(tree,NewTree);
tree=NewTree;
cout<<"交换成功!\n";
cout<<"先序遍历的结果为:";
PreOrderTraverse(tree);
cout<<endl;
}
运行结果为:
测试案例中的 ABD###CE##F## 指的即是如下的这颗二叉树,#代表着^的位置,即代表着该二叉树为空。
补充:中序遍历的非递归算法
基本思想:
1、建立一个栈
2、根结点进栈,遍历左子树
3、根结点出栈,输出根结点,遍历右子树
具体代码如下:
// 中序遍历的非递归算法
#include<iostream>
using namespace std;
//二叉树的二叉链表存储表示
typedef struct BiNode
{
char data; //结点数据域
struct BiNode *lchild,*rchild; //左右孩子指针
}BiTNode,*BiTree;
//链栈的定义
typedef struct StackNode
{
BiTNode data;
struct StackNode *next;
}StackNode,*LinkStack;
//用算法5.3 先序遍历的顺序建立二叉链表
void CreateBiTree(BiTree &T)
{
//按先序次序输入二叉树中结点的值(一个字符),创建二叉链表表示的二叉树T
char ch;
cin >> ch;
if(ch=='#') T=NULL; //递归结束,建空树
else{
T=new BiTNode;
T->data=ch; //生成根结点
CreateBiTree(T->lchild); //递归创建左子树
CreateBiTree(T->rchild); //递归创建右子树
} //else
} //CreateBiTree
void InitStack(LinkStack &S)
{
//构造一个空栈S,栈顶指针置空
S=NULL;
}
bool StackEmpty(LinkStack S)
{
if(!S)
return true;
return false;
}
void Push(LinkStack &S,BiTree e)
{
//在栈顶插入元素*e
StackNode *p=new StackNode;
p->data=*e;
p->next=S;
S=p;
}
void Pop(LinkStack &S,BiTree e)
{
if(S!=NULL)//原书上写的是if(S==NULL)return ERROR;
{
*e=S->data;
StackNode *p=S;
S=S->next;
delete p;
}
}
void InOrderTraverse1(BiTree T)
{
// 中序遍历二叉树T的非递归算法
LinkStack S; BiTree p;
BiTree q=new BiTNode;
InitStack(S); p=T;
while(p||!StackEmpty(S)) //若栈为空则结束循环
{
if(p)
{
Push(S,p); //p非空根指针进栈,遍历左子树
p=p->lchild;
}
else
{
Pop(S,q); //p为空根指针退栈,访问根结点,遍历右子树
cout<<q->data;
p=q->rchild;
}
} // while
} // InOrderTraverse
int main()
{
BiTree tree;
cout<<"请输入建立二叉链表的序列:\n";
CreateBiTree(tree);
cout<<"中序遍历的结果为:\n";
InOrderTraverse1(tree);
cout<<endl;
}