实验目的:
用二叉链表存储方式存储二叉树,并实现以下相关算法:
1、创建二叉树
2、用非递归算法先中后序遍历二叉树
3、分别求出二叉树中度为0、1、2的结点个数
4、求出树的高度
5、销毁二叉树
实验代码如下:
#include
#include
#include
using namespace std; //输入输出cin cout必须要带
#define OK 1
#define ERROR 0
#define OVERFLOW -1
#define MAXSIZE 100
char ch;
typedef char TElemType;
typedef int Status;
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
BiTNode *T;
BiTree q, p;
typedef BiTree SElemType;
typedef struct { //定义顺序栈
SElemType *base;
SElemType *top;
int stacksize;
} SqStack;
SqStack S;
Status InitStack(SqStack &S) {
S.base = new SElemType[MAXSIZE];
if(!S.base) exit(OVERFLOW);
S.top = S.base;
S.stacksize = MAXSIZE;
return OK;
}
Status Push(SqStack &S, SElemType e) { //入栈
if(S.top - S.base == S.stacksize) //判断栈满
return ERROR;
*S.top++ = e; //元素e压入栈顶,栈顶指针上移一位;
return OK;
}
Status Pop(SqStack &S, SElemType &e) { //出栈
if(S.top == S.base) return ERROR;
e = *--S.top;
return OK;
}
SElemType GetTop(SqStack S) { //取栈顶元素
if(S.top != S.base) return *(S.top - 1);
}
Status StackEmpty(SqStack &S) {
if(S.top - S.base == 0) return OK;
else return ERROR;
}
void CreatBiTree(BiTree &T) { //建树
cin >> ch; //读入字符
if(ch == '#') T = NULL; //如果字符为'#',说明已经到了叶结点
else { //递归
T = new BiTNode;
T->data = ch;
CreatBiTree(T->lchild);
CreatBiTree(T->rchild);
}
}
void PreOrderTraverse(BiTree T) { //非递归先序
InitStack(S); //初始化栈S
p = T;
while(p || !StackEmpty(S)) { //如果树不为空或者栈不为空
if(p) {
Push(S, p) ; //将结点入栈
cout << p->data; //输出根结点的值
p = p->lchild ; //把左孩子作为根节点
} else { //如果树空,说明左树已经遍历完成
Pop(S, p) ; //弹出结点
p = p->rchild ; //开始遍历右树
}
}
}
void InOrderTraverse(BiTree T) { //非递归中序遍历
InitStack(S); //初始化栈
p = T;
q = new BiTNode;
while(p || !StackEmpty(S)) {
if(p) { //p非空
Push(S, p); //根指针进栈
p = p->lchild; //根指针进栈,遍历左子树
} else { //p为空
Pop(S, q); //退栈
cout << q->data; //访问根结点
p = q->rchild; //遍历右子树
}
}
}
void PostOrderTraverse(BiTree T) { //非递归后序遍历
InitStack(S);
Push(S, T); //把根节点进栈
BiTNode *pre, *cur;
cur = NULL; //当前结点
pre = NULL; //上一结点
while(!StackEmpty(S)) { //栈非空
cur = GetTop(S); //把根节点给当前结点
if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild || pre == cur->rchild))) {
//如果左右子树都没有或者左右子树都已经访问过了
cout << cur->data; //直接输出根结点
Pop(S, cur); //将此时的根节点弹出
pre = cur; //更新pre
} else { //记得先进右子树后进左子树,这样输出的顺序才对。
if(cur->rchild != NULL) { //如果右子树不为空
Push(S, cur->rchild) ;//把右子树进栈
}
if(cur->lchild != NULL) { //如果左子树不为空
Push(S, cur->lchild) ;//把左子树进栈
}
}
}
}
/*分别求出二叉树中度为0、1、2的结点个数*/
//二叉树的度为0的结点个数
int CountLeaf0 (BiTree T, int& count0) {
if ( T ) {
if (T->lchild == NULL&&T->rchild == NULL)
count0++; // 对叶子结点计数
CountLeaf0( T->lchild, count0);
CountLeaf0( T->rchild, count0);
}
return count0;
}
//二叉树的度为1的结点个数
int CountLeaf1 (BiTree T, int& count1) {
if ( T ) {
if ((T->lchild == NULL &&T->rchild != NULL)||(T->lchild != NULL &&T->rchild == NULL))
count1++; // 对叶子结点计数
CountLeaf1( T->lchild, count1);
CountLeaf1( T->rchild, count1);
}
return count1;
}
//二叉树的度为2的结点个数
int CountLeaf2 (BiTree T, int& count2) {
if ( T ) {
if (T->lchild != NULL&&T->rchild != NULL)
count2++; // 对叶子结点计数
CountLeaf2( T->lchild, count2);
CountLeaf2( T->rchild, count2);
}
return count2;
}
/*求出树的高度*/
int Depth (BiTree T) { // 返回二叉树的深度
int depthLeft;
int depthRight;
int depthval;
if ( !T ) depthval = 0;
else {
depthLeft = Depth( T->lchild );
depthRight= Depth( T->rchild );
depthval = 1 + (depthLeft > depthRight ? depthLeft : depthRight);
}
return depthval;
}
/*销毁二叉链表*/
void DestroyBiTree(BiTree &T) {
if (T) return;
else {
DestroyBiTree(T->lchild);
DestroyBiTree(T->rchild);
free(T);
}
}
int main() {
BiTree T;
int num0,num1,num2;
int height;
int count0 = 0;
int count1 = 0;
int count2 = 0;
printf("请输入二叉树,'#'为空\n");
CreatBiTree(T);
printf("\n非递归先序遍历\n");
PreOrderTraverse(T);
printf("\n非递归中序遍历\n");
InOrderTraverse(T);
printf("\n非递归后序遍历\n");
PostOrderTraverse(T);
printf("\n二叉树的度为0的结点个数:");
num0 = CountLeaf0(T,count0);
printf("%d\n",num0);
printf("\n二叉树的度为1的结点个数:");
num1 = CountLeaf1(T,count1);
printf("%d\n",num1);
printf("\n二叉树的度为2的结点个数:");
num2 = CountLeaf2(T,count2);
printf("%d\n",num2);
printf("\n求出树的高度:");
height = Depth(T);
printf("%d\n",height);
DestroyBiTree(T);
return 0;
}