二叉树非递归遍历

本文探讨了两种非递归遍历二叉树的方法:一种侧重于任务书和子树处理,另一种利用路径分析记录节点信息,尤其在先序和后序遍历中的应用。在先序遍历中,关注路径中的右儿子,而后序遍历则需要通过状态判断来确定何时输出节点。

 第一种 任务书

cas记一下是要遍历子树还是输出节点

第二种 路径分析(带_的)

把路径有用的信息记下来

如先序遍历记一下路径的所有右儿子

后序麻烦一点,cas记情况,0遍历了左子树,1遍历了右子树,遍历了右子树后可以输出,出栈

#include <cstdio>
#include <iostream>
#include <cstring>

using namespace std;

typedef struct Node {
	char val;
	Node *lch,*rch;
	Node(char val='#'):val(val),lch(NULL),rch(NULL){}
}*TNode;

struct Stack{TNode rt;bool cas;}st[100];
int tp;

void build(TNode &T) {
	char c; cin >> c;
	if (c == '#') return;
	T = new Node(c);
	build(T->lch);
	build(T->rch);
}

void Out() {
	for (int i = 1; i <= tp; i++)
		 cout << st[i].rt->val << " " << st[i].cas<<"\n";
	puts("END");
}

void TraP(TNode T) {
	tp = 1;
	st[tp].rt = T;
	st[tp].cas = 1;
	while (tp) {
		TNode t = st[tp].rt;
		if (st[tp--].cas) {
			if (t->rch) {st[++tp].rt = t->rch; st[tp].cas = 1;}
			if (t->lch) {st[++tp].rt = t->lch; st[tp].cas = 1;}
			st[++tp].rt = t; st[tp].cas = 0;
		} else {
			printf("%c",t->val);
		}
	}
	puts("");
}

void TraM(TNode T) {
	tp = 1;
	st[tp].rt = T;
	st[tp].cas = 1;
	while (tp) {
		TNode t = st[tp].rt;
//cout<<(t->val)<<" "<<(st[tp].cas)<<"\n";
		if (st[tp--].cas) {
			if (t->rch) {st[++tp].rt = t->rch; st[tp].cas = 1;}
			st[++tp].rt = t; st[tp].cas = 0;
			if (t->lch) {st[++tp].rt = t->lch; st[tp].cas = 1;}
		} else {
			printf("%c",t->val);
		}
	//	Out();
//		cout << tp << "\n";
	}
	puts("");
}

void TraN(TNode T) {
	tp = 1;
	st[tp].rt = T;
	st[tp].cas = 1;
	while (tp) {
		TNode t = st[tp].rt;
		if (st[tp--].cas) {
			st[++tp].rt = t; st[tp].cas = 0;
			if (t->rch) {st[++tp].rt = t->rch; st[tp].cas = 1;}
			if (t->lch) {st[++tp].rt = t->lch; st[tp].cas = 1;}
		} else {
			printf("%c",t->val);
		}
	}
	puts("");
}

void _TraP(TNode T) {
	st[++tp].rt = T;
	while (tp) {
		TNode t = st[tp--].rt;
		while (t) {
			printf("%c",t->val);
			if(t->rch) st[++tp].rt = t->rch;
			t = t->lch;
		}
	}
	puts("");
}

void _TraM(TNode T) {
	TNode t = T;
	//while (t) {
		while(t) {
			st[++tp].rt = t;
			t = t->lch;
		}
		while(tp) {
		    t = st[tp--].rt;
		    printf("%c",t->val);
		    if (t->rch)  {
				t = t->rch;
				while(t) {
				  st[++tp].rt = t;
				  t = t->lch;
				}
			}
		}	
//	}
	puts("");	
}


void _TraN(TNode T) {
	bool cas[100] = {0};
  TNode t = T;
	while(t) {
		st[++tp].rt = t;
		cas[tp] = 0;
		t = t->lch;
	}
	while(tp) {
			t = st[tp].rt;
			if (cas[tp] == 0) {
				cas[tp] = 1;
				t = t->rch;
				while(t) {
	      	st[++tp].rt = t;
		      cas[tp] = 0;
		      t = t->lch;
	      }
			} else {
				tp--;
				printf("%c",t->val);
		  }
	}	
}

int main() {
	TNode T;
	build(T);
	TraP(T); _TraP(T);
	TraM(T); _TraM(T);
	TraN(T); _TraN(T);
	return 0;
}
// abc#d###ef##g##

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值