算法源码之非递归创建/遍历二叉树

     递归创建二叉树很简单,主要使用系统提供的栈,效率不是很高。将隐式栈转换为显示栈,就归结为非递归形式了。

     在前序、中序、后序非递归创建二叉树中,后序创建稍微绕了一点。

     同样,本文没有分析其原理、以及算法的时间、空间复杂度,这些东西在设计算法的时候要考虑,

     将其现于纸上,繁琐。

#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();
}

运行示例:


 

 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值