- 编程实现二叉树的建立,先序、中序、后序、层序遍历(递归和非递归方法),二叉树的高度、交换左右子树,统计叶子节点的数目,判断是否为完全二叉树,按树的形态在屏幕上打印输出。
#include
#include
#include
#define maxsize 32
#define OVERFLOW -2
struct BT
{
char data;
struct BT *left;
struct BT *right;
};
struct QQ
{
struct BT *ss[maxsize];
int front;
int rear;
};
struct ST
{
struct BT *ss[maxsize];
int top;
};
void enqueue(struct QQ *Q,struct BT *tt);//入队
struct BT *dequeue(struct QQ *Q);//出队
void initial(struct QQ *Q);//初始化队列
void push(struct ST *S,struct BT *tt);//入栈
struct BT *pop(struct ST *S);//出栈
void inistack(struct ST *S);//初始化栈
int menu_select();//菜单程序
struct BT *createbt(struct BT *root);//创建二叉树(先序)
void printbt(struct BT *root,int layer);//输出二叉树树形
void inorderbt(struct BT *root);//中序遍历
void postorderbt(struct BT *root);//后序遍历
void preorderbt(struct BT *root);//先序遍历
void layerbt(struct BT *root);//层次遍历
void swap_left_right(struct BT *root);//交换左右子树
int computheight(struct BT *root);//计算二叉树的高度
int computleaf(struct BT *root);//统计叶子节点的数量
int completbt(struct BT *root);//判断是否为完全二叉树
void initial(struct QQ *Q)//初始化队列
{
Q->front=Q->rear=0;
}
void inistack(struct ST *S) //初始化栈
{
S->top=-1;
}
void enqueue(struct QQ *Q,struct BT *tt) //入队
{
Q->ss[Q->rear]=tt;
Q->rear=Q->rear+1;
}
struct BT *dequeue(struct QQ *Q) //出队
{
struct BT *r;
r=Q->ss[Q->front];
Q->front=Q->front+1;
return r;
}
struct BT *pop(struct ST *S) //出栈
{
struct BT *p;
p=(struct BT *)malloc(sizeof(struct BT));
if(S->top==-1)
{
printf("栈空\n");
return NULL;
}
else
{
p=(S->ss[S->top]);
S->top--;
return p;
}
free(p);
}
void push(struct ST *S,struct BT *tt) //入栈
{
if(S->top==maxsize-1)
{
printf("栈满\n");
}
else
{
S->top++;
S->ss[S->top]=tt;
}
}
struct BT *createbt(struct BT *root)//创建二叉树(先序)
{
char ch;
scanf("%c",&ch);
if(ch==' ')
root=NULL;
else
{
root=(struct BT *)malloc(sizeof(struct BT));
if(!root)
exit(OVERFLOW);
root->data=ch;
root->left=createbt(root->left);//递归构造左子树
root->right=createbt(root->right);
}
return root;
}
void printbt(struct BT *root,int layer)//输出树形
{
int i;
if(!root) return;
printbt(root->right,layer+2);
for(i=0;i
printf(" ");
printf("%c\n",root->data);
printbt(root->left,layer+2);
}
void inorderbt(struct BT *root) //中序遍历
{
if(root!=NULL)
{
inorderbt(root->left);
printf("%c",root->data);
inorderbt(root->right);
}
}
void postorderbt(struct BT *root) //后序遍历
{
struct ST S;
struct BT *p;
int flag; //root的访问标记
inistack(&S);
do
{
while(root)
{
push(&S,root);
root=root->left;
}
p=NULL; //p指向当前结点的前一个已访问的结点
flag=1; //设置root的访问标记已被访问过
while(S.top!=-1&&flag)
{
root=S.ss[S.top];
if(root->right==p) //右子树不存在或已被访问,访问之
{
printf("%c",root->data);
S.top--;
p=root;
}
else
{
root=root->right; //指向右子树
flag=0; //设置未被访问的标记
}
}
}while(S.top!=-1);
}
void preorderbt(struct BT *root) //先序遍历
{
struct ST S;
struct BT p;
if(root!=NULL)
{
inistack(&S);
push(&S,root);
while(S.top>=0)
{
p=*pop(&S); //退栈并访问该结点
printf("%c",p.data);
if(p.right!=NULL) //右孩子入栈
{
push(&S,p.right);
}
if(p.left!=NULL)
{
push(&S,p.left);
}
}
}
}
void swap_left_right(struct BT *root) //交换左右子树
{
struct BT *p;
if(root!=NULL)
{
p=root->left;
root->left=root->right;
root->right=p;
swap_left_right(root->left);
swap_left_right(root->right);
}
}
void layerbt(struct BT *root) //层次遍历
{
struct QQ q;
initial(&q);
if(root!=NULL)
printf("%c",root->data);
enqueue(&q,root);
while(q.front
{
root=dequeue(&q);
if(root->left!=NULL) //输出左孩子,并入队列
{
printf("%c",root->left->data);
enqueue(&q,root->left);
}
if(root->right!=NULL) //输出右孩子,并入队列
{
printf("%c",root->right->data);
enqueue(&q,root->right);
}
}
}
int computheight(struct BT *root) //计算二叉树的高度
{
int leftdep,rightdep;
if(root==NULL)
{
return 0;
}
else
{
leftdep=computheight(root->left);
rightdep=computheight(root->right);
if(leftdep>rightdep)
return(leftdep+1);
else
return(rightdep+1);
}
}
int computleaf(struct BT *root)//统计叶子节点的数量
{
struct ST S;
struct BT p;
int n=0;
if(root!=NULL)
{
inistack(&S);
push(&S,root);
while(S.top>=0)
{
p=*pop(&S); //退栈并访问该结点
if(p.left==NULL&&p.right==NULL)
n++;
if(p.right!=NULL) //右孩子入栈
{
push(&S,p.right);
}
if(p.left!=NULL)
{
push(&S,p.left);
}
}
}
return n;
}
int completbt(struct BT *root)//判断是否为完全二叉树
{
struct BT *p;
struct QQ q;
int bj=1,cm=1;//cm表示整个二叉树是否为完全二叉树
//bj表示到目前为止所有结点均有左右孩子
initial(&q);
if(root!=NULL)
{
enqueue(&q,root);
while(q.front!=q.rear) //队列不空
{
p=dequeue(&q);
if(p->left==NULL)
{
bj=0;
if(p->right!=NULL)
cm=0;
}
else
{
cm=bj;
enqueue(&q,p->left);
if(p->right==NULL)
bj=0;
else
{
enqueue(&q,p->right);
}
}
}
return cm;
}
return 1;
}
int menu_select()//菜单界面
{
char i;
do{
system("cls");
printf("1.创建二叉树(请输入节点值:)\n");
printf("2.显示二叉树\n");
printf("3.中序遍历\n");
printf("4.后序遍历\n");
printf("5.先序遍历\n");
printf("6.层次遍历\n");
printf("7.交换左右子树\n");
printf("8.树的高度及叶子节点的数量\n");
printf("9.是否为完全二叉树\n");
printf("0.退出\n");
printf("请输入选择序号(0-9):");
scanf("%c",&i);
}while(i<'0' || i>'9');
getchar();
return (i-'0');
}
main()
{
struct BT *T;
int layer=0,leafnumber=0;
for(;;)
{
switch(menu_select())
{
case 1:
printf("创建二叉树\n");
T=createbt(T);
printf("二叉树创建完成!\n");
system("pause");
break;
case 2:
printf("显示二叉树\n");
printbt(T,layer);
system("pause");
break;
case 3:
printf("中序遍历结果:\n");
inorderbt(T);
system("pause");
break;
case 4:
printf("后序遍历结果:\n");
postorderbt(T);
system("pause");
break;
case 5:
printf("先序遍历结果 :\n");
preorderbt(T);
system("pause");
break;
case 6:
printf("层次遍历结果:\n");
layerbt(T);
system("pause");
break;
case 7:
printf("交换左右子树 :\n");
swap_left_right(T);
printf("左右子树交换成功\n");
system("pause");
break;
case 8:
printf("树的高度= ,叶子节点数量= :\n");
layer=computheight(T);
printf("树的高度为%d\n",layer);
leafnumber=computleaf(T);
printf("叶子结点数量为%d\n",leafnumber);
system("pause");
break;
case 9:
printf("是否为完全二叉树 :\n");
if(completbt(T))
printf("该树是完全二叉树\n");
else
printf("该树不是完全二叉树\n");
system("pause");
break;
case 0:
printf("再见\n");
system("pause");
exit(0);
}
}
}