(1)将一棵二叉树的所有结点存储在一维数组中,虚结点用#表示,利用二叉树性质5,建立二叉树的二叉链表。
(2) 写出对用二叉链表存储的二叉树进行先序、中序和后序遍历的递归和非递归算法。
(3)写出对用二叉链表存储的二叉树进行层次遍历算法。
(4)求二叉树的所有叶子及结点总数。
//Sinhaeng Hhjian
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define MAX 100005
typedef struct BTNode{
char data;
struct BTNode *lchild, *rchild;
}BTNode, *BiTree;
struct Queue{
BiTree *base;
int f, r;
};
void InitQueue(Queue &q){
q.base = (BiTree *)malloc(sizeof(BiTree) * MAX);
q.f = q.r = 0;
}
void InQueue(Queue &q, BiTree bt){
q.base[q.r++] = bt;
}
int IsEmpty(Queue q){
return q.f == q.r? 1:0;
}
void OutQueue(Queue &q, BiTree &bt){
if(IsEmpty(q)) return ;
bt = q.base[q.f++];
}
void CreatBiTree(BiTree &bt, char *Data, int n){
Queue Q;
int Qnum[MAX], f, r, i;
BiTree p;
if(n<1){
bt = NULL;
return;
}
bt = (BiTree)malloc(sizeof(BTNode));
bt->data = Data[1];
InitQueue(Q); InQueue(Q, bt);
f = r = 0;
Qnum[r++]=1;
while(!IsEmpty(Q)){
OutQueue(Q, p); i=Qnum[f++];
if(2*i > n || Data[2*i] == '#')
p->lchild = NULL;
else{
p->lchild = (BiTree)malloc(sizeof(BTNode));
p->lchild->data = Data[2*i];
InQueue(Q, p->lchild);
Qnum[r++] = 2*i;
}
if(2*i+1 > n || Data[2*i+1] == '#')
p->rchild = NULL;
else{
p->rchild = (BiTree)malloc(sizeof(BTNode));
p->rchild->data = Data[2*i+1];
InQueue(Q, p->rchild);
Qnum[r++] = 2*i+1;
}
}
}
void PreOrderTraverse(BiTree bt){
if(bt){
printf("%3c", bt->data);
PreOrderTraverse(bt->lchild);
PreOrderTraverse(bt->rchild);
}
}
void InOrderTraverse(BiTree bt){
if(bt){
InOrderTraverse(bt->lchild);
printf("%3c", bt->data);
InOrderTraverse(bt->rchild);
}
}
void PostOrderTraverse(BiTree bt){
if(bt){
PostOrderTraverse(bt->lchild);
PostOrderTraverse(bt->rchild);
printf("%3c", bt->data);
}
}
struct Stack{
BiTree *base;
int top;
};
void Push(Stack &s, BiTree bt){
s.base[++s.top] = bt;
}
int GetTop(Stack s, BiTree &bt){
if(!s.top)
return 0;
bt = s.base[s.top];
return 1;
}
int IsSEmpty(Stack s){
return s.top==0? 1 : 0;
}
void InitStack(Stack &s){
s.base = (BiTree *)malloc(MAX*(sizeof(BiTree)));
s.top=0;
}
void Pop(Stack &s, BiTree &bt){
if(IsSEmpty(s))
return ;
bt = s.base[s.top];
s.top--;
}
void PreOrderTraverse2(BiTree bt){
if(bt){
Stack S;
BiTree p;
InitStack(S);
Push(S, bt);
while(!IsSEmpty(S)){
while(GetTop(S, p) && p){
printf("%3c", p->data);
Push(S, p->lchild);
}
Pop(S, p);
if(!IsSEmpty(S)){
Pop(S, p);
Push(S, p->rchild);
}
}
}
}
void InOrderTraverse2(BiTree bt){
if(bt){
Stack S;
BiTree p;
InitStack(S);
Push(S, bt);
while(!IsSEmpty(S)){
while(GetTop(S, p) && p)
Push(S, p->lchild);
Pop(S, p);
if(!IsSEmpty(S)){
Pop(S, p);
printf("%3c", p->data);
Push(S, p->rchild);
}
}
}
}
void PostOrderTraverse2(BiTree bt){
if(bt){
Stack S;
BiTree p, q;
InitStack(S);
Push(S, bt);
while(!IsSEmpty(S)){
while(GetTop(S, p) && p)
Push(S, p->lchild);
Pop(S, p);
if(!IsSEmpty(S)){
GetTop(S, p);
if(p->rchild)
Push(S, p->rchild);
else{
Pop(S, p);
printf("%3c", p->data);
while(!IsSEmpty(S) && GetTop(S, q) && q->rchild == p){
Pop(S, p);
printf("%3c", p->data);
}
if(!IsSEmpty(S)){
GetTop(S, p);
Push(S, p->rchild);
}
}
}
}
}
}
void LevelOrderTraverse(BiTree bt){
if(bt){
Queue Q;
BiTree p;
InitQueue(Q);
InQueue(Q, bt);
while(!IsEmpty(Q)){
OutQueue(Q, p);
printf("%3c", p->data);
if(p->lchild)
InQueue(Q, p->lchild);
if(p->rchild)
InQueue(Q, p->rchild);
}
}
}
void CountLeaf(BiTree bt, int &leaves, int &cnt, char *lea){
if(bt){
cnt++;
CountLeaf(bt->lchild, leaves, cnt, lea);
if(!bt->lchild && !bt->rchild)
lea[leaves++]=bt->data;
CountLeaf(bt->rchild, leaves, cnt, lea);
}
}
int main(){
BiTree bt;
char date[MAX];
printf("请输入一维数组结构的二叉树:\n");
scanf("%s", date+1);
int n=strlen(date+1);
CreatBiTree(bt, date, n);
printf("递归先序遍历:");
PreOrderTraverse(bt);
printf("\n");
printf("递归中序遍历:");
InOrderTraverse(bt);
printf("\n");
printf("递归后序遍历:");
PostOrderTraverse(bt);
printf("\n\n");
printf("非递归先序遍历:");
PreOrderTraverse2(bt);
printf("\n");
printf("非递归中序遍历:");
InOrderTraverse2(bt);
printf("\n");
printf("非递归后序遍历:");
PostOrderTraverse2(bt);
printf("\n\n");
printf("层次遍历:");
LevelOrderTraverse(bt);
printf("\n\n");
int cnt=0, sum=0;
char leaves[MAX];
CountLeaf(bt, sum, cnt, leaves);
printf("叶子节点总数为:%d\n", sum);
printf("分别是:");
for(int i=0;i<sum;i++)
printf("%3c", leaves[i]);
printf("\n节点总数为:%d\n", cnt);
return 0;
}