实验三
一、实验目的
1、掌握二叉树的存储实现。
2、掌握二叉树的遍历思想。
3、掌握二叉树的常见算法的程序实现。
二、实验仪器及环境:
PC计算机;windows XP操作系统、Visual C++6.0
三、实验内容及结果(按照具体实验题目,按照如下格式书写)
1、 按先序次序输入二叉树中结点的值(一个字符),利用某个特殊字符(例如`@`)表示空树,生成二叉树的二叉链表存储结构。
2、 按先、中、后序递归遍历二叉树,之后结合栈的应用,将中序遍历算法改为非递归算法。
3、利用二叉树的递归算法求二叉树的高度 。
4、利用二叉树的递归算法求二叉树的叶子个数。
5、利用队列实现二叉树的层次遍历。
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
#define M 100
#define MAXQSIZE 100
typedef char ElemType; ///元素类型
typedef struct Node
{ ElemType data;
struct Node *lchild,*rchild;
}BTNode,*BiTree;
void PreOrderTraverse(BiTree T){///先序遍历二叉树的递归算法
if (T){
printf("%c",T->data);
PreOrderTraverse(T->lchild);
PreOrderTraverse(T->rchild);
}
}
void InOrderTraverse(BiTree T){///中序遍历二叉树的递归算法
if (T) {
InOrderTraverse(T->lchild);
printf("%c",T->data);
InOrderTraverse(T->rchild);
}
}
void PostOrderTraverse(BiTree T){///后序遍历二叉树的递归算法
if (T) {
PostOrderTraverse(T->lchild);
PostOrderTraverse(T->rchild);
printf("%c",T->data);
}
}
void visit(BiTree p)
{
printf("%c",p->data);
}
void nInOrder(BiTree t) ///中根次序遍历的非递归算法
{ int i;
BiTree p,s[M];
p=t;i=0;
if (t == NULL) return;
do
{ while (p != NULL)
{s[i]=p;i++; p = p->lchild ; }
if (i>0)
{i--;p=s[i]; visit(p); p=p->rchild;}
}while(i>0|| p!= NULL);
}
BiTree CreateBiTree()///创建二叉树
{ BiTree T;
char ch; scanf("%c",&ch);
if (ch=='@') T=NULL;
else
{
T=(BTNode *)malloc(sizeof(BTNode));
T->data = ch; //生成根结点
T->lchild=CreateBiTree(); //生成左子树
T->rchild=CreateBiTree(); //生成右子树
}
return T;
}
int Depth(BiTree T){///求二叉树深度
int depl,depr;
if (T==NULL) return 0;
else {
depl=Depth(T->lchild);
depr=Depth(T->rchild);
if (depl>=depr) return (depl+1);
else return (depr+1);
}
}
int LeafCount(BiTree T) ///求叶子结点的个数
{if(!T) return 0; //空树没有叶子
else
if(T->lchild==NULL&&T->rchild==NULL) return 1; //叶子结点
else return LeafCount(T->lchild)+LeafCount(T->rchild);
//左子树叶子数加上右子树叶子数
}
typedef struct{
BiTree base[MAXQSIZE];
int front,rear;
}SqQueue;
void InitQueue(SqQueue &q)
{
q.front=q.rear=0;
}
void LevelOrderTraverse(BiTree T)
{ BiTree p; SqQueue Q; InitQueue(Q);
if (T){ Q.base[Q.rear]=T;
Q.rear=(Q.rear+1)%MAXQSIZE;
while (Q.front !=Q.rear)
{ p=Q.base[Q.front];
printf("%c",p->data);
Q.front=(Q.front+1)%MAXQSIZE;
if (p->lchild)
{ Q.base[Q.rear]=p->lchild;
Q.rear=(Q.rear+1)%MAXQSIZE;}
if (p->rchild)
{ Q.base[Q.rear]=p->rchild;
Q.rear=(Q.rear+1)%MAXQSIZE;} } }
}
int main()
{
printf("按先序次序输入二叉树中结点的值\n");
BiTree q=CreateBiTree();
printf("先序递归遍历二叉树:\n");
PreOrderTraverse(q);
printf("\n中序递归遍历二叉树:\n");
InOrderTraverse(q);
printf("\n后序递归遍历二叉树:\n");
PostOrderTraverse(q);
printf("\n中序非递归遍历二叉树:\n");
nInOrder(q);
int high=Depth(q);
printf("\n树的高度是:%d\n",high);
high=LeafCount(q);
printf("\n树的叶子节点的个数是:%d\n",high);
printf("\n层序遍历二叉树:\n");
LevelOrderTraverse(q);
return 0;
}
四、实验心得体会:(包括遇到的问题及解决办法)
首先要确定一个二叉树是要知道中序遍历结果加一个先序或后序的遍历结果,也就是要有两个遍历方式才能确定一颗树,起初因为这个想法,没看懂@的意思,后来经人指导,才知道@表示空节点,这样也可以确定唯一的一颗二叉树,真是奇妙啊。在编程过程中,有时手误敲的一些小错误会使程序出错,一定要注意啊。