二叉树的非递归遍历

二叉树的非递归遍历需要用到栈,三种遍历方法中最麻烦的是后序遍历,因为它需要访问根结点2次,故在第一次访问的时候需要标示它的访问状态。

#include <iostream>
#include <stack>

using namespace std;

typedef struct _Tree{
	int data;
	struct _Tree *left;
	struct _Tree *right;
} Tree;

typedef struct _Visit {
	Tree *node;
	bool visited;	//访问标志
} Visit;

void PrePrintTree(Tree *root) {
	if (NULL == root)
		return;
	Tree *p = root;
	stack<Tree*> stk;
	stk.push(p);
	while (!stk.empty()) {
		Tree *cur = stk.top();
		stk.pop();
		cout << cur->data << ' '; //先输出,再push右结点,push左结点(先pop左,再pop右,从而是先序遍历)
		if (cur->right != NULL)
			stk.push(cur->right);
		if (cur->left != NULL)
			stk.push(cur->left);
	}
	cout << endl;
}

void InPrintTree(Tree *root) {
	if (NULL == root)
		return;
	Tree *p = root;
	stack<Tree*> stk;
	while (p != NULL) {  //1. 一路将左结点push到栈中,相当于左结点优先处理过了
		stk.push(p);
		p = p->left;
	}
	while (!stk.empty()) {
		Tree *cur = stk.top();
		stk.pop();
		cout << cur->data << ' '; //2. 输出中间结点
		if (cur->right != NULL) { //3. 将右结点按步骤1处理
			cur = cur->right;
			while (cur != NULL) {
				stk.push(cur);
				cur = cur->left;
			}
		}
	}
	cout << endl;
}

void PostPrintTree(Tree *root) {
	if (NULL == root)
		return;
	Tree *p = root;
	stack<Visit> stk;
	while (p != NULL) {  //1. 一路将左结点push到栈中,相当于左结点优先处理过了
		Visit v = {p, false};
		stk.push(v);
		p = p->left;
	}
	while (!stk.empty()) {
		Visit cur = stk.top();
		stk.pop();
		//2. 当前结点是第一次访问,且有右结点没有处理,则修改访问标志,再次push当前结点
		//然后按步骤1处理当前结点的右结点
		if (cur.node->right != NULL && cur.visited == false) {
			Visit v = {cur.node, true}; //修改访问标志为true,再次push当前结点
			stk.push(v);
			p = cur.node->right;
			while (p != NULL) {
				Visit v = {p, false};
				stk.push(v);
				p = p->left;
			}
		} else {
			cout << cur.node->data << ' '; //3. 当前结点处理后,输出
		}
	}
	cout << endl;
}

int main()
{
	Tree a1 = {1, NULL, NULL};
	Tree a2 = {2, NULL, NULL};
	Tree a3 = {3, NULL, NULL};
	Tree a4 = {4, NULL, NULL};
	Tree a5 = {5, &a1, &a2};
	Tree a6 = {6, &a3, &a4};
	Tree a7 = {7, &a5, &a6};
	PrePrintTree(&a7);
	InPrintTree(&a7);
	PostPrintTree(&a7);
	return 0;
}

输出:

7 5 1 2 6 3 4
1 5 2 7 3 6 4
1 2 5 3 4 6 7


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值