C Language 二叉树 - 二叉树的遍历(十四)

Posted Adorable_Rocy

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C Language 二叉树 - 二叉树的遍历(十四)相关的知识,希望对你有一定的参考价值。

二叉树遍历有多种方式,先序、中序、后序、层次遍历四种遍历方式,下面一起来看看吧

补充:关于四种遍历方式已经在上一篇文章中给出:Tree和BinaryTree(十三)


1.二叉树的递归遍历算法

先:ABDHEFCGI
中:HDBEFACIG
后:HDFEBIGCA

有二叉树如下:
A(B(D(H),E(,F)),C(,G(I))

1.先序遍历

//先序输出
void PreOrder(BTNode *bnode){
	if(bnode!=NULL){
		printf("%3c",bnode->data);
		PreOrder(bnode->lchild);
		PreOrder(bnode->rchild);
	}
} 

2.中序遍历

//中序输出
void InOrder(BTNode *bnode){
	if(bnode!=NULL){
		InOrder(bnode->lchild);
			printf("%3c",bnode->data);
		InOrder(bnode->rchild);
	}
} 

3.后序遍历

//后序输出
void PostOrder(BTNode *bnode){
	if(bnode!=NULL){
		PostOrder(bnode->lchild);
		PostOrder(bnode->rchild);
			printf("%3c",bnode->data);
	}
} 

输出结果如下:

2.二叉树的非递归算法

前言:关于二叉树的非递归算法,可以采用栈的运算算法进行设计,先进栈的后出栈的原则,进行算法的设计。

1.先序遍历

//非递归的先序算法 
void SqStackPreOrder(BTNode *bnode) {
	BTNode *b;
	SqStack *st;
	initStack(st);  //初始化栈
	if(bnode != NULL) {
		Push(st,bnode);   	   //进栈操作
		while(!StackEmpty(st)) {  //栈不为空时循环
			Pop(st,b);  	 //退栈
			printf("%3c",b->data);	//输出元素
			if(b->rchild != NULL) {			//先进后出 先序是DLR 所以先进R然后出R 
				Push(st,b->rchild);
			} 
			if(b->lchild != NULL){
				Push(st,b->lchild);
			}
		}
	}
}

2.中序遍历

//中序非递归算法 
void SqStackInOrder(BTNode *bnode) {
	BTNode *b;
	SqStack *st;
	initStack(st);  //初始化栈
	b = bnode;
	while(!StackEmpty(st)|| b != NULL) {
		while(b != NULL) {  //扫描所有的左子树并且一一添加 
				Push(st,b);
				b = b->lchild;  //一直添加 
		}
		
		//右子树的左子树  到最左下角 然后出栈最左下角的元素 再添加右子树的结点 
		//如果右子树没有左子树了 就继续出栈 
		if(!StackEmpty(st)){
			Pop(st,b); 			//出栈元素
			printf("%3c",b->data);
			b = b->rchild; 
		}
	}
	printf("\\n"); 
}

3.后续遍历

//后序遍历的非递归算法
void SqStackPostOrder(BTNode *bnode){
	BTNode *b , *r;
	bool flag;
	SqStack *st;
	initStack(st);
	b = bnode;
	do{
		while(b != NULL){		//顺序入栈 左子树进栈 
			Push(st,b);
			b = b->lchild;	
		}
		r = NULL;				//初始化指针r 
		flag = true;     		//表示正在处理的栈顶结点
		while(!StackEmpty(st) && flag){
			GetTop(st,b);			//取出栈顶结点p 
			if(b->rchild == r){ 	//如果结点为空或者为刚访问过的结点 
				printf("%3c",b->data);
				Pop(st,b);
				r = b;		//r指向之前访问过的结点 
			}else{
				b = b->rchild;
				flag = false;
			}
		} 
	}while(!StackEmpty(st));
	printf("\\n");
}

  • 附赠:完整代码如下:
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
#define MaxSons 5
#define MaxSize 20

typedef struct SqNode {
	char data;
	struct SqNode *lchild;
	struct SqNode *rchild;
} BTNode;

//创建栈
typedef struct {
	BTNode *data[MaxSize];
	int top;
} SqStack;

//创建二叉树
void createBiTree(BTNode *&node , char *str) {

	BTNode *St[MaxSize] , *p; //创建顺序栈
	int top = -1,k,j = 0; //栈顶指针以及str数组指针
	char ch ;
	node = NULL;
	ch = str[j];
	while(ch != '\\0') { //循环遍历str数值
		switch(ch) {
			case '(':
				top++;
				St[top] = p;
				k=1;
				break;
			case ')':
				top--;
				break;
			case ',':
				k=2;
				break;
			default:
				p = (BTNode *)malloc(sizeof(BTNode));
				p->data = ch;
				p->lchild = p->rchild = NULL;
				if(node == NULL) {
					node = p;
				} else {
					switch(k) {
						case 1:
							St[top]->lchild = p;
							break;
						case 2:
							St[top]->rchild = p;
							break;
					}
				}
		}
		j++;
		ch = str[j];
	}
}
//输出二叉树
void dispBtree(BTNode *b) {
	if(b!=NULL) {
		printf("%c",b->data);
		if(b->lchild != NULL || b->rchild != NULL) {
			printf("(");
			dispBtree(b->lchild);
			if(b->rchild != NULL) printf(",");
			dispBtree(b->rchild);
			printf(")");
		}
	}
}
//销毁二叉树
void  destoryBTree(BTNode *&bnode) {
	if(bnode != NULL) {
		destoryBTree(bnode->lchild);
		destoryBTree(bnode->rchild);
		free(bnode);
	}
}
//查找结点算法
BTNode *findNode(BTNode *bnode , char ch) {
	BTNode *p;
	if(bnode == NULL) {
		//没有返回值了
		return NULL;
	} else if(bnode->data == ch) {
		return bnode;
	} else {
		p = findNode(bnode->lchild,ch);
		if(p != NULL) {
			return p;
		} else {
			return findNode(bnode->rchild,ch);
		}
	}
}

//先序输出
void PreOrder(BTNode *bnode) {
	if(bnode!=NULL) {
		printf("%3c",bnode->data);
		PreOrder(bnode->lchild);
		PreOrder(bnode->rchild);
	}
}
//中序输出
void InOrder(BTNode *bnode) {
	if(bnode!=NULL) {
		InOrder(bnode->lchild);
		printf("%3c",bnode->data);
		InOrder(bnode->rchild);
	}
}
//后序输出
void PostOrder(BTNode *bnode) {
	if(bnode!=NULL) {
		PostOrder(bnode->lchild);
		PostOrder(bnode->rchild);
		printf("%3c",bnode->data);
	}
}

//初始化栈
void initStack(SqStack *&st) {
	st = (SqStack *)malloc(sizeof(SqStack));
	st->top = -1;
}

//判断栈是否为空栈
int StackEmpty(SqStack *st){
	return st->top == -1 ? 1 : 0;
} 
//获取栈顶元素
BTNode *GetTop(SqStack *st , BTNode *&b){
	if(StackEmpty(st)){
		return NULL;
	}
	b = st->data[st->top];
	return b;
} 
//进栈操作
void Push(SqStack *&st , BTNode *bnode){
	st->top = st->top + 1; 
	st->data[st->top] = bnode;
} 


//出栈
BTNode Pop(SqStack *st , BTNode *&b){
	b = st->data[st->top];
	st->top = st->top - 1;
	return *b; 
} 

//非递归的先序算法 
void SqStackPreOrder(BTNode *bnode) {
	BTNode *b;
	SqStack *st;
	initStack(st);  //初始化栈
	if(bnode != NULL) {
		Push(st,bnode);   	   //进栈操作
		while(!StackEmpty(st)) {  //栈不为空时循环
			Pop(st,b);  	 //退栈
			printf("%3c",b->data);	//输出元素
			if(b->rchild != NULL) {			//先进后出 先序是DLR 所以先进R然后出R 
				Push(st,b->rchild);
			} 
			if(b->lchild != NULL){
				Push(st,b->lchild);
			}
		}
	}
}

//中序非递归算法 
void SqStackInOrder(BTNode *bnode) {
	BTNode *b;
	SqStack *st;
	initStack(st);  //初始化栈
	b = bnode;
	while(!StackEmpty(st)|| b != NULL) {
		while(b != NULL) {  //扫描所有的左子树并且一一添加 
				Push(st,b);
				b = b->lchild;  //一直添加 
		}
		
		//右子树的左子树  到最左下角 然后出栈最左下角的元素 再添加右子树的结点 
		//如果右子树没有左子树了 就继续出栈 
		if(!StackEmpty(st)){
			Pop(st,b); 			//出栈元素
			printf("%3c",b->data);
			b = b->rchild; 
		}
	}
	printf("\\n"); 
}
//后序遍历的非递归算法
void SqStackPostOrder(BTNode *bnode){
	BTNode *b , *r;
	bool flag;
	SqStack *st;
	initStack(st);
	b = bnode;
	do{
		while(b != NULL){		//顺序入栈 左子树进栈 
			Push(st,b);
			b = b->lchild;	
		}
		r = NULL;	//初始化指针r 
		flag = true;
		while(!StackEmpty(st) && flag){
			GetTop(st,b);			//取出栈顶结点p 
			if(b->rchild == r){ 	//如果结点为空或者为刚访问过的结点 
				printf("%3c",b->data);
				Pop(st,b);
				r = b;		//r指向之前访问过的结点 
			}else{
				b = b->rchild;
				flag = false;
			}
		} 
	}while(!StackEmpty(st));
	printf("\\n");
}

main() {
	BTNode *bnode , *p;
	char *str = "A(B(D(H),E(,F)),C(,G(I))";
	createBiTree(bnode,str);
	dispBtree(bnode);
	printf("\\n");
	SqStackPreOrder(bnode);
	printf("\\n");
	SqStackInOrder(bnode);
	SqStackPostOrder(bnode);

	return 0;
}

以上是关于C Language 二叉树 - 二叉树的遍历(十四)的主要内容,如果未能解决你的问题,请参考以下文章

为啥树的后根遍历对应二叉树的中序遍历

C语言数据结构“遍历二叉树”

根据二叉树的前序遍历和中序遍历构建二叉树的c语言完整代码

二叉树的遍历

C语言,如何用非递归方法输出二叉树的根到所有叶子路径?

数据结构《四》二叉树的实现