递归创建二叉树很简单,主要使用系统提供的栈,效率不是很高。将隐式栈转换为显示栈,就归结为非递归形式了。
在前序、中序、后序非递归创建二叉树中,后序创建稍微绕了一点。
同样,本文没有分析其原理、以及算法的时间、空间复杂度,这些东西在设计算法的时候要考虑,
将其现于纸上,繁琐。
#include<stdio.h>
#include<stdlib.h>
#define SIZE 8
typedef struct BTree{
char data;
struct BTree *LChild;
struct BTree *RChild;
}BTree;
typedef struct Stack{
BTree *bt;
}Stack;
void createBTree(){
BTree *bt,*root,*p,*q;
char ch;
int top=-1;
Stack s[SIZE];
ch=getchar();
root=bt=(BTree*)malloc(sizeof(BTree)); //先创建根结点
bt->data=ch;
top++;
s[top].bt=bt; //根结点地址入栈
do{
while(bt!=NULL){ //若当前结点不为空则,创建左孩子
ch=getchar();
if(ch==' '){ //若输入空格,则代表结点为空
bt->LChild=NULL;
bt=bt->LChild;
}
else {
bt->LChild=(BTree*)malloc(sizeof(BTree));//若输入的不为空格
bt->LChild->data=ch; //则分配空间,建立左结点
top++;
s[top].bt=bt->LChild; //并将创建的结点地址入栈
bt=bt->LChild; //让bt指向当前刚创建的结点
}
}; // 若上面的循环结束,此时左孩子创建完毕/
if(top!=-1){ //出栈
bt=s[top].bt;
top--;
ch=getchar();
if(ch==' '){
bt->RChild=NULL;
bt=bt->RChild;
}
else { //若输入的字符不是空格,则对刚出栈的结点创建右子树
bt->RChild=(BTree*)malloc(sizeof(BTree));
bt->RChild->data=ch;
top++;
s[top].bt=bt->RChild; //并将刚创建的结点地址入栈
bt=bt->RChild; //让bt指向当前刚创建的结点
}
} //只要bt不为空,或者top不等于-1,就继续做循环
}while(bt!=NULL||top!=-1);
printf("二叉树创建完毕!\n");
//中序非递归遍历
top=-1; //创建完二叉树,栈已经为空了,故可以重复利用
printf("中序非递归遍历结果\n");
p=root; //将根结点赋给p
do{ //只要p不为空,或者top不等于-1,就继续做循环
while(p!=NULL){
top++;
s[top].bt=p;//结点入栈
p=p->LChild;//继续遍历,直到左孩子为空
};
if(top!=-1){
p=s[top].bt; //根出栈
top--;
printf(" %c",p->data);//访问根结点
p=p->RChild; //若有右孩子,则访问
}
}while(p!=NULL||top!=-1);
printf("\n");
printf("前序非递归遍历结果\n");
top=-1;
p=root;
do{
while(p!=NULL){
printf(" %c",p->data);//访问根结点
top++;
s[top].bt=p;
p=p->LChild; //中序遍历左子树
};
if(top!=-1){
p=s[top].bt;
top--;
p=p->RChild;//中序遍历右子树
}
}while(p!=NULL||top!=-1);
printf("\n");
printf("后序非递归遍历结果\n"); //后序非递归遍历
top=-1;
q=NULL;
p=root;
while(p!=NULL||top!=-1){
while(p!=NULL){
top++;
s[top].bt=p;
p=p->LChild;
};
if(top!=-1){
p=s[top].bt;
if((p->RChild==NULL)||(p->RChild==q)){
printf(" %c",p->data);
q=p;
top--;
p=NULL;
}
else p=p->RChild;
}
};
printf("\n");
}
void main(){
printf("输入非空字符代表非叶结点,输入空格代表叶节点\n");
createBTree();
}
运行示例: