(1)输入完全二叉树的先序序列,用#代表虚结点(空指针),如ABD###CE##F##,建立二叉树的二叉链表。
(2)写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。(3)写出对用二叉链表存储的二叉树进行层次遍历算法。
(4)求二叉树的所有叶子及结点总数。
(5)求二叉树的深度。

代码:

#include<stdio.h>
#include<stdlib.h>

#define StackInitSize 100 // 栈初始大小
#define StackIncrement 10 //栈存储空间增量

#define QMAXSIZE 100 //循环队列的初始大小

typedef struct BiTNode{ //二叉树
char data;
struct BiTNode *lchild,*rchild;
}BiTNode,*BiTree;

typedef BiTree BT;

typedef struct{ //栈
BT *base;
BT *top;
int stacksize;
}SqStack;

typedef struct{ //队列
BT *base;
int front,rear;
}CqQueue;

//栈操作*//
void InitStack(SqStack &S){
S.base = (BT*)malloc(StackInitSize*sizeof(BT));
if(!S.base)
return ;
S.top = S.base;
S.stacksize = StackInitSize;
}

int StackEmpty(SqStack S){
if(S.top == S.base)
return 1;
return 0;
}

void Push(SqStack &S,BT e){
if(S.top-S.base >= S.stacksize){
S.base = (BT*)realloc(S.base,(S.stacksize+StackIncrement)*sizeof(BT));
if(!S.base)
return ;
S.top = S.base + StackIncrement;
S.stacksize += StackIncrement;
}
*S.top++ = e;
}

void Pop(SqStack &S,BT &e){
if(S.top== S.base)
return ;
e = *–S.top;
}

BT GetTop(SqStack S,BT &e){
if(S.top == S.base)
return NULL;
e = *(S.top-1);
return e;
}

//队列操作//
void InitQueue(CqQueue &Q){
Q.base = (BT
)malloc(QMAXSIZE*sizeof(BT));
if(!Q.base)
return ;
Q.front = Q.rear =0;
}

int QueueEmpty(CqQueue Q){
if(Q.rear == Q.front)
return 1;
return 0;
}

void EnQueue(CqQueue &Q,BT e){
if((Q.rear+1) % QMAXSIZE == Q.front )
return ;
Q.base[Q.rear] = e;
Q.rear = (Q.rear+1)%QMAXSIZE;
}

void DeQueue(CqQueue &Q,BT &e){
if(Q.front == Q.rear)
return ;
e = Q.base[Q.front];
Q.front = (Q.front+1)%QMAXSIZE;
}

//*********************************//

void CreateBiTree_1(BiTree &bt){
//输入完全二叉树的先序序列建立二叉树的二叉链表
char ch;
ch = getchar();//或scanf("%c",&ch);
if(ch == ‘#’)
bt = NULL;
else{
if(!(bt = (BiTNode*)malloc(sizeof(BiTNode))))
return ;
bt->data = ch; //生成根结点
CreateBiTree_1(bt->lchild); //先序建立左子树
CreateBiTree_1(bt->rchild); //右子树
}
}
void visit(char s){
//访问结点
printf("%c ",s);
}

//递归算法遍历二叉树*//
void Rec_PreOrderTraverse(BiTree bt){
//先序遍历
if(bt){
visit(bt->data); //访问根结点
Rec_PreOrderTraverse(bt->lchild); //先序遍历左子树
Rec_PreOrderTraverse(bt->rchild); //先序遍历右子树
}
}
void Rec_InOrderTraverse(BiTree bt){
//中序遍历
if(bt){
Rec_InOrderTraverse(bt->lchild); //先序遍历左子树
visit(bt->data); //访问根结点
Rec_InOrderTraverse(bt->rchild); //先序遍历右子树
}
}
void Rec_PostOrderTraverse(BiTree bt){
//后序遍历
if(bt){
Rec_PostOrderTraverse(bt->lchild); //先序遍历左子树
Rec_PostOrderTraverse(bt->rchild); //先序遍历右子树
visit(bt->data); //访问根结点
}
}
//非递归算法遍历二叉树*//
void NotRec_PreOrderTraverse(BiTree bt,SqStack S){
//先序遍历
BT p;
if(bt){
InitStack(S);
Push(S,bt); //根节点入栈
while(!StackEmpty(S)){
while(GetTop(S,p) && p){ //栈顶元素为非空值
visit(p->data);
Push(S,p->lchild); //向左走到尽头
}
Pop(S,p); //空结点出栈
if(!StackEmpty(S)){
Pop(S,p);
Push(S,p->rchild);
}
}//while
}//if
}
void NotRec_InOrderTraverse(BiTree bt,SqStack S){
//中序遍历 仅将先序遍历中的visit函数调用 放在Pop函数后面即可
BT p;
if(bt){
InitStack(S);
Push(S,bt);
while(!StackEmpty(S)){
while(GetTop(S,p) && p){
Push(S,p->lchild);
}
Pop(S,p);
if(!StackEmpty(S)){
Pop(S,p);
visit(p->data);
Push(S,p->rchild);
}
}//while
}//if
}
void NotRec_PostOrderTraverse(BiTree bt,SqStack S){
//后序遍历
BT p,q;
if(bt){
InitStack(S);
Push(S,bt);
while(!StackEmpty(S)){
while(GetTop(S,p) && p) //遍历左子树
Push(S,p->lchild);
Pop(S,p); //空结点出栈
if(!StackEmpty(S)){ //遍历右子树
GetTop(S,p);
if(p->rchild) //右子树非空
Push(S,p->rchild); //右子树根结点出栈
else{ //左右子树遍历结束,访问根结点
Pop(S,p);
visit(p->data);
while(!StackEmpty(S) && GetTop(S,q) && q->rchild ==p){ //若访问的结点为其双亲结点的左右孩子,则双亲结点出栈
Pop(S,p);
visit(p->data);
}//while
if(!StackEmpty(S)){ //是栈顶结点的右孩子出栈
GetTop(S,p);
Push(S,p->rchild);
}//if
}//else
}//if
}//while
}//if
}
//*层次遍历//
void LevelOrderTraverse(BiTree bt,CqQueue Q){
if(bt){
BT p;
InitQueue(Q);
EnQueue(Q,bt); //根结点入队列
while(!QueueEmpty(Q)){
DeQueue(Q,p); //队头元素出队列
visit(p->data);
if(p->lchild)
EnQueue(Q,p->lchild); //非空左孩子入队列
if(p->rchild)
EnQueue(Q,p->rchild); //非空右孩子入队列
}//while
}//if
}

void CountLeaf(BiTree bt,int &leaves){
//计算叶子结点数
if(bt){
CountLeaf(bt->lchild,leaves); //遍历左子树
if(!bt->lchild && !bt->rchild) //计算叶子结点数
leaves++;
CountLeaf(bt->rchild,leaves); //遍历右子树
}
}
int BiTreeDepth(BiTree bt){
//计算二叉树的深度
int depthL,depthR;
if(bt == NULL)
return 0;
else{
depthL = BiTreeDepth(bt->lchild);
depthR = BiTreeDepth(bt->rchild);
if(depthL >= depthR)
return depthL+1;
else
return depthR+1;
}
}

void main(){
int b,leaves;
leaves = 0; //叶子节点数
SqStack S; //栈
InitStack(S);
CqQueue Q; //队列
InitQueue(Q);
BiTree bt; //二叉树
printf(“请输入完全二叉树的二先序序列:\n”);
CreateBiTree_1(bt);
printf(“递归算法遍历二叉树:\n”);
printf(“先序遍历:”);
Rec_PreOrderTraverse(bt);
printf("\n");
printf(“中序遍历:”);
Rec_InOrderTraverse(bt);
printf("\n");
printf(“后序遍历:”);
Rec_PostOrderTraverse(bt);
printf("\n");
printf(“非递归算法遍历二叉树:\n”);
printf(“先序遍历:”);
NotRec_PreOrderTraverse(bt,S);
printf("\n");
printf(“中序遍历:”);
NotRec_InOrderTraverse(bt,S);
printf("\n");
printf(“后序遍历:”);
NotRec_PostOrderTraverse(bt,S);
printf("\n");
printf(“层次遍历二叉树:”);
LevelOrderTraverse(bt,Q);
printf("\n");
printf(“叶子节点数为:”);
CountLeaf(bt,leaves);
printf("%d\n",leaves);
printf(“二叉树的深度为:”);
b=BiTreeDepth(bt);
printf("%d\n",b);
}

运行结果:
2019-11-19
2019-11-19

相关文章: