二叉树的创建与遍历

 二叉树的创建只要循环创建左子树,右子树就好了,注意输入时一定要输子树为空的地方,比如每个叶子节点后面都要跟两个空;

二叉树的递归遍历很简单,按顺序遍历就好;

先序遍历:根->左->右;

中序遍历:左->根->右;

后序遍历:左->右->根;

非递归遍历时要利用栈存储一下遍历过的节点,以便后续查找;

先序遍历:每次输出根节点并进栈,然后找左子树,循环,直到节点为空,然后取栈顶节点并出栈,找此节点的右子树;

先序遍历:每次找根节点并进栈,然后找左子树,循环,直到节点为空,然后取栈顶节点,输出此节点,并出栈,找此节点的右子树;

后序遍历:每次找根节点并进栈,然后找左子树,循环,直到节点为空;然后判断栈顶节点的左右子树是否全部遍历过,若是,输出节点并出栈,否则,遍历右子树;

 

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

typedef struct node{//定义节点结构
	char data;
	node *lchild,*rchild;
}bintnode,*bintree;

typedef struct{//栈结构定义,用来进行非递归遍历 
	bintree data[110];//存放节点 
	int tag[110];//后序遍历时用来标记 
	int top;//栈顶指针 
}stack;

void push(stack *s,bintree t){//t进栈 
	s->data[s->top++]=t;
} 

void pop(stack *s){//出栈
    s->top--; 
}

bintree createbintree(){//创建二叉树 
	char ch;
	bintree t;
	ch=getchar();
    //getchar();  
//这里输入直接连着输入,如果想输一个字符换行一下把getchar()解掉注释就好了
	if(ch=='/') t = NULL;
	else{
		t = (bintree)malloc(sizeof(bintnode));
		t->data = ch;
		t->lchild = createbintree();
		t->rchild = createbintree();
	}
	return t;
}

void preorder(bintree t){//先序递归遍历 
	if(t==NULL) return;
	printf("%c->",t->data);
	preorder(t->lchild);
	preorder(t->rchild);
}

void preorder1(bintree t){//先序非递归遍历
	stack s;
	s.top = 0;//初始化栈
	while(t || s.top){//栈不为空并且节点不为空
		while(t){
			printf("%c->",t->data);//先输出根节点
			push(&s,t);//按顺序放进栈中
			t = t->lchild;//根节点下来是左子树
		}
		if(s.top){//如果栈不为空
			t = s.data[--s.top];//t等于栈末节点,并删除节点
			t = t->rchild;
		}
	}
} 

void inorder(bintree t){//中序递归遍历 
	if(t==NULL) return;
	inorder(t->lchild);
	printf("%c->",t->data);
	inorder(t->rchild);
}

void inorder1(bintree t){//中序非递归遍历
	stack s;
	s.top = 0;
	while(t || s.top){
		while(t){
			push(&s,t);
			t = t->lchild;
		}
		if(s.top){
			t = s.data[--s.top];
			printf("%c->",t->data);//先输出左子树
			t = t->rchild;
		}
	}	
}
void postorder(bintree t){//后序递归遍历 
	if(t==NULL) return;
	postorder(t->lchild);
	postorder(t->rchild);
	printf("%c->",t->data);
}

void postorder1(bintree t){//后序非递归遍历 
	stack s;
	s.top = 0;
	while(t || s.top){
		while(t){
			s.tag[s.top]=0;//表示只访问过左子树
			push(&s,t);
			t = t->lchild;			
		}
		if(s.top){
			if(s.tag[s.top-1]){//如果左右子树都访问过了
			    t = s.data[--s.top];//才能删除根节点
			    printf("%c->",t->data);//再输出根节点
				t = NULL;	
			}
			else{//否则要访问右子树
			    t = s.data[s.top-1];
			    s.tag[s.top-1]=1;
			    t = t->rchild;				
			}
		}
	} 
}	

int main()
{
	bintree t;
	printf("请按照前序遍历输入二叉树(子节为空请输入'/'):\n");
	t = createbintree();
	printf("\n");
	
	printf("二叉树的前序递归遍历结果为:\n");
	printf("begin->");
	preorder(t);
	printf("end!\n");
	printf("\n");

	printf("二叉树的前序非递归遍历结果为:\n");
	printf("begin->");
	preorder1(t);
	printf("end!\n");
	printf("\n");
		
	printf("二叉树的中序递归遍历结果为:\n");
	printf("begin->");
	inorder(t);
	printf("end!\n");
	printf("\n");	
		
	printf("二叉树的中序非递归遍历结果为:\n");
	printf("begin->");
	inorder1(t);
	printf("end!\n");
	printf("\n");
		
	printf("二叉树的后序递归遍历结果为:\n");
	printf("begin->");
	postorder(t);
	printf("end!\n");	
	printf("\n");
		
	printf("二叉树的后序非递归遍历结果为:\n");
	printf("begin->");
	postorder1(t);
	printf("end!\n");	
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值