树的非递归遍历

非递归遍历树算法以前我一直死记书本的用栈保存,最近笔试时要求写非递归遍历,想了很久都没有写好。回家后,我回顾重新学习了这个非递归遍历算法,总结了一下于是写下来记下。

其实遍历每个节点的过程中,有三种状态是必须记录下的,1、没访问左子树。2、已访问左子树。3、没访问右子树。每种状态须要执行的操作分别是,1、左孩子节点入栈,2、访问结点信息(中序遍历),3、右孩子节点入栈。其中已访问左子树,由下图的虚线表示,并且此时进行访问节点信息和弹栈操作。

非递归遍历算法,状态2的表示是关键,这个可以通过检测其是不是NULL节点返回来判断。

 

#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<stack>
#include<algorithm>
using namespace std;

struct Node{
	int value;
	Node *L, *R;
};
#define MemNode(nd) nd=(Node*)malloc(sizeof(*nd))
void CreateTree(Node *&root){
	MemNode(root);
	root->value = 1;
	MemNode(root->L);
	MemNode(root->R);
	Node *L = root->L;
	Node *R = root->R;
	R->value = 4;
	R->L = R->R = NULL;
	
	L->value = 2;
	L->L = NULL;
	MemNode(L->R);
	L->R->value = 3;
	L->R->L = L->R->R = NULL;
}

int dfs(Node *p){
	if (p->L == NULL && p->R == NULL) {
		printf("%d\n",p->value);
		return p->value;
	}
	int lv = 0, rv = 0;
	if (p->L) lv = dfs(p->L);
	printf("%d\n", p->value);
	if (p->R) rv = dfs(p->R);
	return lv + rv + p->value;
}
void visit(Node *p,int &sum){
	sum += p->value;
	printf("%d\n",p->value);
}
int traverse(Node *p){
	stack<Node*> stTree;
	stTree.push(p);
	int sum = 0;
	while (!stTree.empty()){
		Node *nd = stTree.top(); 
		if (nd != NULL){
			stTree.push(nd->L);
		}else{
			stTree.pop();
			if (!stTree.empty()){
				Node *tp = stTree.top(); stTree.pop();
				visit(tp, sum);
				stTree.push(tp->R);
			}
		}
	}
	return sum;
}

int main(){
	Node *root = NULL;
	CreateTree(root);
	int dfsTot = dfs(root);
	printf("sum = %d\n",dfsTot);
	printf("=================================================================");
	puts("\nNon-recursive Traverse");
	int traTot = traverse(root);
	printf("sum = %d\n",traTot);
	return 0;
}

上面代码CreateTree是创建如图所示结构的树,dfs使用递归遍历树并求和,traverse使用了非递归算法。
 

编码请看:http://www.maidoupig.cn

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值