数据结构二叉树的操作遍历及树形输出.docx
《数据结构二叉树的操作遍历及树形输出.docx》由会员分享,可在线阅读,更多相关《数据结构二叉树的操作遍历及树形输出.docx(18页珍藏版)》请在冰豆网上搜索。
数据结构二叉树的操作遍历及树形输出
/*实验三:
二叉树遍历操作验证*/
#include
#include
#include
#include
#include
#include
#include
usingnamespacestd;
#defineOK1
#defineERROR0
#defineOVERFLOW-2
intLeafNum;//叶子结点个数
//定义结构体
typedefstructBiTNode{
chardata;//存放值
structBiTNode*lchild,*rchild;//左右孩子
}BiTNode,*BiTree;
//先序输入二叉树结点的值,空格表示空树
voidcreateBiTree(BiTree&T)
{
charch;//输入结点时用
scanf("%c",&ch);
if(ch=='')//若输入空格,该值为空,且没有左右孩子
{
T=NULL;
}else{
T=(BiTNode*)malloc(sizeof(BiTNode));//分配结点空间
if(!
T)//分配失败
{
exit(OVERFLOW);
}
T->data=ch;//生成根结点
createBiTree(T->lchild);//构造左子树
createBiTree(T->rchild);//构造右子树
}
}
//递归方法先序遍历二叉树
voidpreOrderTraverse(BiTreeT)
{
if(T)//若非空
{
if(T->data)
{//输出
printf("%c",T->data);
}
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
}
//递归方法中序遍历二叉树
voidinOrderTraverse(BiTreeT)
{
if(T)//若非空
{
preOrderTraverse(T->lchild);
if(T->data)
{//输出
printf("%c",T->data);
}
preOrderTraverse(T->rchild);
}
}
//递归方法后序遍历二叉树
voidpostOrderTraverse(BiTreeT)
{
if(T)//若非空
{
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
if(T->data)
{//输出
printf("%c",T->data);
}
}
}
//层序遍历二叉树
voidLevelTraverse(BiTreeT)
{
queueq;//建队
q.push(T);//根节点入队
BiTreep;
while(!
q.empty())
{
p=q.front();//获得队列的首元素
q.pop();//首元素出队
cout<data<<"";//输出结点的值
if(p->lchild!
=NULL)//若结点的左孩子不空
{
q.push(p->lchild);
}
if(p->rchild!
=NULL)//若结点的右孩子不空
{
q.push(p->rchild);
}
}
}
//非递归方法前序遍历二叉树
voidstackPreOrderTraverse(BiTreeT)
{
stacks;//建栈
s.push(T);//根结点入栈
BiTreep;//栈首元素
while(!
s.empty())
{
while((p=s.top())&&p)
{
printf("%c",p->data);
s.push(p->lchild);//左孩子入栈,直到走到尽头
}
s.pop();//空指针出栈
if(!
s.empty())
{
p=s.top();//获得栈顶元素
s.pop();//出栈
s.push(p->rchild);//右孩子入栈
}
}
}
//非递归方法中序遍历二叉树
voidstackInOrderTraverse(BiTreeT)
{
stacks;//建栈
s.push(T);//入栈
BiTreep;//栈首元素
while(!
s.empty())
{
while((p=s.top())&&p)
{
s.push(p->lchild);//左孩子入栈,直到走到尽头
}
s.pop();//空指针出栈
if(!
s.empty())
{
p=s.top();
s.pop();//出栈
printf("%c",p->data);
s.push(p->rchild);//右孩子入栈
}
}
}
//非递归方法后序遍历二叉树
voidstackPostOrderTraverse(BiTreeT)
{
stacks;//建栈
mapm;//标记结点是否已经输出
BiTreep;//栈首元素
if(T)//若不是空树
{
s.push(T);//根结点入栈
}
while(!
s.empty())
{
while(true)
{//目的:
找到后序遍历要输出的结点
while((p=s.top())&&p->lchild&&!
m[p->lchild])
{//若左孩子未输出,将左孩子入栈,直到尽头,不包括空指针
s.push(p->lchild);
}
if((p=s.top())&&p->rchild&&!
m[p->rchild])
{//若最左孩子的右孩子未输出且非空,则入栈
s.push(p->rchild);
}else{
break;//找到结点跳出循环
}
}
if((p=s.top())&&!
m[p])
{
printf("%c",p->data);
m[p]=true;//标记已经输出
s.pop();//退栈
}
}
}
//后序遍历求二叉树的高度递归算法
intPostTreeDepth(BiTreeT)
{
inthl,hr,max;
if(T!
=NULL)
{
hl=PostTreeDepth(T->lchild);//求左子树的深度
hr=PostTreeDepth(T->rchild);//求右子树的深度
max=hl>hr?
hl:
hr;//得到左、右子树深度较大者
return(max+1);//返回树的深度
}
else
return(0);//如果是空树,则返回0
}
/*按竖向树状打印的二叉树代码是为了实现二叉树的横向显示问题。
这种树形要求先打印右子树,再打印根,最后打印左子树,顺序恰为逆中序顺序。
这种输出格式,结点的左右位置与结点的层深有关,
故算法中设置了一个表示当前根节点层深的参数,以控制输出结点的左右位置。
*/
voidPrintTree(BiTreeT,intnLayer)
{
inti;
if(T==NULL)return;
PrintTree(T->rchild,nLayer+1);
for(i=0;iprintf("");
printf("%c\n",T->data);
PrintTree(T->lchild,nLayer+1);
}
//叶子结点的个数以及元素
intTreeLeaf(BiTreeT)
{
if(T)
{
if(!
T->lchild&&!
T->rchild)
{
LeafNum++;
cout<data<<"";
}
TreeLeaf(T->lchild);
TreeLeaf(T->rchild);
}
returnLeafNum;
}
intmain()
{
BiTreeT;//定义结点
intlayer=0;//层数
while(true)
{
cout<<"输入二叉树结点值空格表示空树:
"<createBiTree(T);
cout<<"递归先序遍历:
";
preOrderTraverse(T);
cout<cout<<"递归中序遍历:
";
inOrderTraverse(T);
cout<cout<<"递归后序遍历:
";
postOrderTraverse(T);
cout<cout<<"层序遍历:
";
LevelTraverse(T);
cout<cout<<"非递归先序遍历:
";
stackPreOrderTraverse(T);
cout<cout<<"非递归中序遍历:
";
stackInOrderTraverse(T);
cout<cout<<"非递归后序遍历:
";
stackPostOrderTraverse(T);
cout<cout<<"叶子结点为:
";
cout<<"叶子结点个数为:
"<cout<<"树的的深度:
";
layer=PostTreeDepth(T);
cout<cout<<"二叉树的树形结构图:
"<PrintTree(T,layer);
}
return0;
}
/*实验三:
二叉树遍历操作验证*/
#include
#include
#include
#include
#include
#include
#include
usingnamespacestd;
#defineOK1
#defineERROR0
#defineOVERFLOW-2
intLeafNum;//叶子结点个数
//定义结构体
typedefstructBiTNode{
chardata;//存放值
structBiTNode*lchild,*rchild;//左右孩子
}BiTNode,*BiTree;
//先序输入二叉树结点的值,空格表示空树
voidcreateBiTree(BiTree&T)
{
charch;//输入结点时用
scanf("%c",&ch);
if(ch=='')//若输入空格,该值为空,且没有左右孩子
{
T=NULL;
}else{
T=(BiTNode*)malloc(sizeof(BiTNode));//分配结点空间
if(!
T)//分配失败
{
exit(OVERFLOW);
}
T->data=ch;//生成根结点
createBiTree(T->lchild);//构造左子树
createBiTree(T->rchild);//构造右子树
}
}
//递归方法先序遍历二叉树
voidpreOrderTraverse(BiTreeT)
{
if(T)//若非空
{
if(T->data)
{//输出
printf("%c",T->data);
}
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
}
//递归方法中序遍历二叉树
voidinOrderTraverse(BiTreeT)
{
if(T)//若非空
{
preOrderTraverse(T->lchild);
if(T->data)
{//输出
printf("%c",T->data);
}
preOrderTraverse(T->rchild);
}
}
//递归方法后序遍历二叉树
voidpostOrderTraverse(BiTreeT)
{
if(T)//若非空
{
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
if(T->data)
{//输出
printf("%c",T->data);
}
}
}
//层序遍历二叉树
voidLevelTraverse(BiTreeT)
{
queueq;//建队
q.push(T);//根节点入队
BiTreep;
while(!
q.empty())
{
p=q.front();//获得队列的首元素
q.pop();//首元素出队
cout<data<<"";//输出结点的值
if(p->lchild!
=NULL)//若结点的左孩子不空
{
q.push(p->lchild);
}
if(p->rchild!
=NULL)//若结点的右孩子不空
{
q.push(p->rchild);
}
}
}
//非递归方法前序遍历二叉树
voidstackPreOrderTraverse(BiTreeT)
{
stacks;//建栈
s.push(T);//根结点入栈
BiTreep;//栈首元素
while(!
s.empty())
{
while((p=s.top())&&p)
{
printf("%c",p->data);
s.push(p->lchild);//左孩子入栈,直到走到尽头
}
s.pop();//空指针出栈
if(!
s.empty())
{
p=s.top();//获得栈顶元素
s.pop();//出栈
s.push(p->rchild);//右孩子入栈
}
}
}
//非递归方法中序遍历二叉树
voidstackInOrderTraverse(BiTreeT)
{
stacks;//建栈
s.push(T);//入栈
BiTreep;//栈首元素
while(!
s.empty())
{
while((p=s.top())&&p)
{
s.push(p->lchild);//左孩子入栈,直到走到尽头
}
s.pop();//空指针出栈
if(!
s.empty())
{
p=s.top();
s.pop();//出栈
printf("%c",p->data);
s.push(p->rchild);//右孩子入栈
}
}
}
//非递归方法后序遍历二叉树
voidstackPostOrderTraverse(BiTreeT)
{
stacks;//建栈
mapm;//标记结点是否已经输出
BiTreep;//栈首元素
if(T)//若不是空树
{
s.push(T);//根结点入栈
}
while(!
s.empty())
{
while(true)
{//目的:
找到后序遍历要输出的结点
while((p=s.top())&&p->lchild&&!
m[p->lchild])
{//若左孩子未输出,将左孩子入栈,直到尽头,不包括空指针
s.push(p->lchild);
}
if((p=s.top())&&p->rchild&&!
m[p->rchild])
{//若最左孩子的右孩子未输出且非空,则入栈
s.push(p->rchild);
}else{
break;//找到结点跳出循环
}
}
if((p=s.top())&&!
m[p])
{
printf("%c",p->data);
m[p]=true;//标记已经输出
s.pop();//退栈
}
}
}
//后序遍历求二叉树的高度递归算法
intPostTreeDepth(BiTreeT)
{
inthl,hr,max;
if(T!
=NULL)
{
hl=PostTreeDepth(T->lchild);//求左子树的深度
hr=PostTreeDepth(T->rchild);//求右子树的深度
max=hl>hr?
hl:
hr;//得到左、右子树深度较大者
return(max+1);//返回树的深度
}
else
return(0);//如果是空树,则返回0
}
/*按竖向树状打印的二叉树代码是为了实现二叉树的横向显示问题。
这种树形要求先打印右子树,再打印根,最后打印左子树,顺序恰为逆中序顺序。
这种输出格式,结点的左右位置与结点的层深有关,
故算法中设置了一个表示当前根节点层深的参数,以控制输出结点的左右位置。
*/
voidPrintTree(BiTreeT,intnLayer)
{
inti;
if(T==NULL)return;
PrintTree(T->rchild,nLayer+1);
for(i=0;iprintf("");
printf("%c\n",T->data);
PrintTree(T->lchild,nLayer+1);
}
//叶子结点的个数以及元素
intTreeLeaf(BiTreeT)
{
if(T)
{
if(!
T->lchild&&!
T->rchild)
{
LeafNum++;
cout<data<<"";
}
TreeLeaf(T->lchild);
TreeLeaf(T->rchild);
}
returnLeafNum;
}
intmain()
{
BiTreeT;//定义结点
intlayer=0;//层数
while(true)
{
cout<<"输入二叉树结点值空格表示空树:
"<createBiTree(T);
cout<<"递归先序遍历:
";
preOrderTraverse(T);
cout<cout<<"递归中序遍历:
";
inOrderTraverse(T);
cout<cout<<"递归后序遍历:
";
postOrderTraverse(T);
cout<cout<<"层序遍历:
";
LevelTraverse(T);
cout<cout<<"非递归先序遍历:
";
stackPreOrderTraverse(T);
cout<cout<<"非递归中序遍历:
";
stackInOrderTraverse(T);
cout<cout<<"非递归后序遍历:
";
stackPostOrderTraverse(T);
cout<cout<<"叶子结点为:
";
cout<<"叶子结点个数为:
"<cout<<"树的的深度:
";
layer=PostTreeDepth(T);
cout<cout<<"二叉树的树形结构图:
"<PrintTree(T,layer);
}
return0;
}