本篇主要涉及:
二叉树以lson-rson链接方式存储,以菜单方式设计并完成功能任务:建立并存储树、输出前序遍历结果、输出中序遍历结果、输出后序遍历结果、交换左右子树、统计高度,其中对于中序、后序的遍历运算要求采用非递归方式。
话不多说直接上代码:
#include<stdio.h>
#include<stdlib.h>
typedef struct Binary_Tree
{
char data; //结点的数据域
struct Binary_Tree *lson;
struct Binary_Tree *rson;
}TREE,*Binarytree;
//各函数声名
Binarytree recursion_creat(Binarytree T); //运用递归方法创建二叉树
void preorder_traversal(Binarytree T); //前序遍历
void inorder_traversal(Binarytree T); //非递归实现中序遍历
void postorder_traversal(Binarytree T); //非递归实现后序遍历
void exchange_subtree(Binarytree T); //交换左右子树
int height_calculation(Binarytree T); //统计高度
void swap(Binarytree Tree1,Binarytree Tree2);
int main()
{
Binarytree T1,T2;
int height,flag=1;
printf("请依次输入节点的值,以'#'号结束\n\n");
T2=recursion_creat(T1);
printf("\n\n创建成功!\n\n");
while(flag=1)
{
printf("-----------------------------------");
printf("\n");
printf("--------1 输出前序遍历结果----------\n\n");
printf("--------2 输出中序遍历结果----------\n\n");
printf("--------3 输出后序遍历结果----------\n\n");
printf("--------4 交换左右子树--------------\n\n");
printf("--------5 统计二叉树的高度----------\n\n");
printf("--------6 退出----------------------\n\n");
printf("\n\n请输入您的选择:");
int m;
scanf("%d",&m);
switch(m)
{
case 1:
printf("\n\n前序遍历结果为:\n\n");
preorder_traversal(T2);
printf("\n\n");
break;
case 2:
printf("\n\n中序遍历结果为:\n\n");
inorder_traversal(T2);
printf("\n\n");
break;
case 3:
printf("\n\n后序遍历结果为:\n\n");
postorder_traversal(T2);
printf("\n\n");
break;
case 4:
exchange_subtree(T2);
printf("交换成功!");
printf("\n\n");
break;
case 5:
printf("\n\n此二叉树的高度为:\n\n");
height = height_calculation(T2);
printf("%d",height);
printf("\n\n");
break;
case 6:exit(0);
default:printf("输入错误!");break;
}
}
return 0;
}
Binarytree recursion_creat(Binarytree T)
{
char ch;
scanf("%c",&ch);
fflush(stdin);//清除标准输入流的缓存
if(ch!='#')
{
T=(Binarytree)malloc(sizeof(TREE));
T->data=ch;
T->lson=NULL;
T->rson=NULL;
T->lson=recursion_creat(T->lson);
T->rson=recursion_creat(T->rson);
}
return T;
}
void preorder_traversal(Binarytree T)
{
if(T!=NULL)
{
printf("%c",T->data);
//依次遍历左子树和右子树
preorder_traversal(T->lson);
preorder_traversal(T->rson);
}
}
void inorder_traversal(Binarytree T)
{
int index=0; //栈顶
Binarytree data[100];
do
{
while(T!=NULL)
{
index++;
data[index]=T;
T=T->lson;
}
if(index!=0)
{
T=data[index];
index--;
printf("%c",T->data);
T=T->rson;
}
}while(T!=NULL||index!=0);
}
void postorder_traversal(Binarytree T)
{
Binarytree S[100], P;
int flag, top =0;
if (T!= NULL)
{
do{
while(T != NULL)
{
S[top++] = T; //入栈
T= T->lson;//遍历左子树
}
P = NULL;//
flag = 1; //已访问
while(top && flag)
{
T = S[top-1]; //退栈
if(T->rson == P) //
{
printf("%c",T->data);//访问
top--;
P = T;//
}
else
{
T=T->rson;
flag = 0;
}
}
}while(top);
printf("\n\n");
}
}
void exchange_subtree(Binarytree T)
{
if(!T))
{
return;//退出
}
else
{
swap(T->lson,T->rson);
exchange_subtree(T->lson);
exchange_subtree(T->rson);
}
}
void swap(Binarytree Tree1, Binarytree Tree2)
{
Binarytree temp;
temp=Tree1;
Tree1=Tree2;
Tree2=temp;
}
int height_calculation(Binarytree T)
{
int height_lson;
int height_rson;
int max;
if(T==NULL)
{
return 0;
}
height_lson=height_calculation(T->lson);
height_rson=height_calculation(T->rson);
max=height_lson > height_rson ? height_lson : height_rson;
return max+1;
}
关于程序中使用到的fflush()函数:
清除标准输入设备(一般是键盘)的缓存。
scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束)。
① 遇空格、“回车”、“跳格”键。
② 遇宽度结束。
③ 遇非法输入。
键盘缓冲区就可能有残余信息问题。
scanf()函数应该只是扫描stdin流,这个残存信息是在stdin中
解决就要在scanf()函数之后加个fflush(stdin)。
flush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃
fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上。
关于typedef与结构体,我觉得一位大佬写的很好,在此附上链接,侵删:
https://blog.csdn.net/hk121/article/details/80839063
关于非递归实现中序遍历,同样附上一位大佬的博客链接,侵删:
非递归算法详解