二叉树的遍历与求深度的递归与非递归实现

//=========二叉树(Binary Tree)===========
#define _CRT_SECURE_NO_WARNINGS
#include<stack>
#include<queue>
using namespace std;
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#define OVERFLOW -1
#define OK 1
#define ERROR 0
#define max(a , b) (a>b?a:b)//带参宏,听说比使用函数更好(inline)
#define TElemType int
#define Status int

//-----二叉树的链式存储---------------- 
typedef struct BiTNode {
	TElemType data;
	struct BiTNode *lChild, *rChild;
}BiTNode, *BiTree;

//----------基本操作的函数原型说明----------------- 
Status createBiTree(BiTree *T);
Status printBiTree(TElemType *data);
Status Add(TElemType *data);
Status PreorderTraverse(BiTree T, Status(*visit)(TElemType *data));
Status traversePreorder(BiTree T, Status(*visit)(TElemType *data));
Status InorderTraverse(BiTree T, Status(*visit)(TElemType* data));
Status PostorderTraverse(BiTree T, Status(*visit)(TElemType* data));
Status traversePostorder(BiTree T, Status(*visit)(TElemType* data));
Status traverseInorder(BiTree T, Status(*visit)(TElemType* data));
Status LevelOrderTraverse(BiTree T, Status(*visit)(TElemType* data));//层次遍历
int    BiTreeDepth(BiTree T);
int    depdhBiTree(BiTree T);
//Status clearBiTree(BiTree *T);//将树T清为空树
//Status destroyBiTree(BiTree *T);//摧毁二叉树T

//-----------------------------------------------------主函数----------------------------------------------------------------
int main() {
	//paste your code here
	//freopen("d:\\coding\\data.in", "r", stdin);
	BiTree T;
	createBiTree(&T);
	//PreorderTraverse(T, printBiTree);//已测试
	//InorderTraverse(T, printBiTree);//已测试
	//PostorderTraverse(T, printBiTree);//已测试
	//traverseInorder(T, printBiTree);//非递归中序遍历二叉树已测试
	//traversePreorder(T, printBiTree);//非递归先根序遍历二叉树,已测试
	//traversePostorder(T, printBiTree);//递推后根序遍历二叉树,已测试
	//LevelOrderTraverse(T, printBiTree);//层次遍历,已测试
	//printf("%d\n", BiTreeDepth(T));//求二叉树的深度,已测试
	//printf("%d\n",depdhBiTree(T));//递归求二叉树的深度,已测试
	InorderTraverse(T, printBiTree);
	printf("\n");
	traverseInorder(T,Add);
	InorderTraverse(T, printBiTree);

	while (1);
	return 0;
}

Status createBiTree(BiTree *T) {
	TElemType data;
	scanf("%d", &data);
	if (data == -1) (*T) = NULL;//每个叶子节点用-1表示,必须输入 
	else {
		if (!((*T) = (BiTree)malloc(sizeof(BiTNode)))) exit(OVERFLOW);
		(*T)->data = data;
		createBiTree(&((*T)->lChild));
		createBiTree(&((*T)->rChild));
	}

	return OK;
}
Status printBiTree(TElemType *data) {
	printf("%d\t", *data);
	return OK;
}
Status traversePreorder(BiTree T, Status(*visit)(TElemType *data)) {
	stack<BiTree>S;
	BiTree p = T;
	while (!(p == NULL && S.empty())) {
		if (p !=  NULL) {
			visit(&p->data);
			if (p->rChild != NULL) S.push(p->rChild);
			p = p->lChild;
		}
		else {
			p = S.top();
			S.pop();
		}
	}
	return OK;
}
Status traverseInorder(BiTree T, Status(*visit)(TElemType *data)) {
	stack<BiTree>S;
	BiTree p = T;//初始时指针p指向树根
	while (p != NULL || !S.empty()) {//递推结束条件
		while (p != NULL) {
			S.push(p);
			p = p->lChild;
		}		
		//此时p是空的,栈是不空的。因为若栈也空,则递推已经结束了,放心使用取值弹出操作
		p = S.top();
		S.pop();
		visit(&p->data);
		p = p->rChild;		
	}
	return OK;
}
Status traversePostorder(BiTree T, Status(*visit)(TElemType* data)) {
	stack<BiTree>S;
	BiTree p = T,pre=NULL;
	while (!(p == NULL && S.empty())) {
		if (p != NULL) {
			S.push(p);
			p = p->lChild;//直到左孩子为空,栈顶是最左下的节点
		}
		else {
			p = S.top();
			if (p->rChild != NULL && p->rChild!=pre) {//若果右子树存在且未被访问过
				p = p->rChild;
				S.push(p);
				p = p->lChild;
			}
			else {
				visit(&p->data);
				pre = p;
				S.pop();
				p = NULL;
			}
		}
	}//BINGO,设置了一个前驱指针,来区分右子树是否被访问过
	return OK;
}
Status PreorderTraverse(BiTree T, Status(*visit)(TElemType* data)) {
	//先序遍历
	if (T == NULL) return OK;//若二叉树为空,则空操作
	visit(&T->data);//访问根节点
	PreorderTraverse(T->lChild, visit);//先序遍历左子树
	PreorderTraverse(T->rChild, visit);//先序遍历右子树
	return OK;//返回值
}
Status InorderTraverse(BiTree T, Status(*visit)(TElemType* data)) {
	if (T == NULL)return OK;//二叉树为空,则空操作
	InorderTraverse(T->lChild, visit);//中序遍历左子树
	visit(&T->data);//访问根节点
	InorderTraverse(T->rChild, visit);//中序遍历右子树
	return OK;//返回值
}
Status PostorderTraverse(BiTree T, Status(*visit)(TElemType *data)) {
	//后序遍历
	if (T == NULL) return OK;//若二叉树为空,则空操作
	PostorderTraverse(T->lChild, visit);//中序遍历左子树
	PostorderTraverse(T->rChild, visit);//中序遍历右子树
	visit(&T->data);//访问根节点
	return OK;//返回值
}
Status LevelOrderTraverse(BiTree T, Status(*visit)(TElemType* data)) {
	//层次遍历二叉树,理论上用宽度优先搜索的思想可以实现此遍历
	queue<BiTree>Q;
	Q.push(T);
	BiTree p = NULL;
	while (!Q.empty()) {
		p = Q.front();
		visit(&p->data);
		Q.pop();
		if (p->lChild != NULL) {
			Q.push(p->lChild);
		}
		if (p->rChild != NULL) {
			Q.push(p->rChild);
		}
	}//一遍过
	return OK;
}
int    BiTreeDepth(BiTree T) {
	//用深度搜索的思想应该能实现,分递归、递推两种
	int length = 0;//初始化树的深度
	BiTree p = T;
	if (p == NULL) return 0;//递归出口,千万不要死循环了
	length = length + 1 + max(BiTreeDepth(p->lChild), BiTreeDepth(p->rChild));
	return length;//递归还是比较容易实现的
}
int    depdhBiTree(BiTree T) {
	if (T == NULL) return 0;
	int length = 1;//根算一层
	BiTree p = T;
	queue<BiTree>Q;
	Q.push(T);
	Q.push(NULL);//NULL表示一层结束
	while (Q.size()>1) {//有一个层结束标志时而在队列中
		p = Q.front();
		Q.pop();
		if (p != NULL) {
			if (p->lChild != NULL) Q.push(p->lChild);
			if (p->rChild != NULL) Q.push(p->rChild);
		}
		else {
			length++;
			Q.push(NULL);
		}
	}
	return length;
}
Status Add(TElemType *data) {
	(*data)++;
	return OK;
}

//宽度优先搜索BFS用队列;而且深度优先搜索也用队列
//若出现一个无法解析的……,说明函数名写错了
//优先级 ->第一级,*和&同级(自右至左)

/*输入数据:
1 2 8 -1 10 -1 -1 9 -1 -1 3 4 -1 -1 5 -1 6 -1 7 -1 -1
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值