树的非递归遍历(中序遍历)

中序 遍历的几种情况

分析1:什么时候访问根、什么时候访问左子树、什么访问右子树

       当左子树为空或者左子树已经访问完毕以后,再访问根

       访问完毕根以后,再访问右子树。

分析2:非递归遍历树,访问结点时,为什么是栈,而不是其他模型(比如说是队列)。

        先走到的后访问、后走到的先访问,显然是栈结构

分析3:结点所有路径情况

步骤1:

如果结点有左子树,该结点入栈;

如果结点没有左子树,访问该结点;

步骤2:

如果结点有右子树,重复步骤1;

如果结点没有右子树(结点访问完毕),根据栈顶指示回退,访问栈顶元素,并访问右子树,重复步骤1

如果栈为空,表示遍历结束。

注意:入栈的结点表示,本身没有被访问过,同时右子树也没有被访问过。

分析4:有一个一直往左走入栈的操作,中序遍历的起点

// nonrecursion.cpp
// 对树的操作

#include <iostream>
#include <cstdio>
#include <stack>

using namespace std;

// 二叉树表示法
typedef struct BiTNode
{
	int	data;
	struct BiTNode *lchild, *rchild;
}BiTNode, *BiTree;

// 递归中序遍历
void inOrder(BiTNode *T)
{
	if (T == NULL) {
		return;
	}

	inOrder(T->lchild);

	printf("%d ", T->data);

	inOrder(T->rchild);
}

BiTNode* goFarLeft(BiTNode *T, stack<BiTNode *> &s)
{
	if (T == NULL) {
		return NULL;
	}
	while (T->lchild) {
		s.push(T);
		T = T->lchild; // 让指针下移
	}
	return T;
}

void nonRecursionInOrder(BiTNode *T)
{
	stack<BiTNode *> s;
	BiTNode *tmp = goFarLeft(T, s);

	while (tmp) {
		printf("%d ", tmp->data);

		// 若结点有右子树,重复步骤1
		if (tmp->rchild) {
			tmp = goFarLeft(tmp->rchild, s);
		}
		// 若结点没有右子树,看栈是否为空
		else if (!s.empty()) {
			tmp = s.top();
			s.pop();
		}
		else {
			tmp = NULL;
		}
	}
}

void operatorTree()
{
	BiTNode nodeA, nodeB, nodeC, nodeD, nodeE;

	memset(&nodeA, 0, sizeof(BiTNode));
	memset(&nodeB, 0, sizeof(BiTNode));
	memset(&nodeC, 0, sizeof(BiTNode));
	memset(&nodeD, 0, sizeof(BiTNode));
	memset(&nodeE, 0, sizeof(BiTNode));

	nodeA.data = 1;
	nodeB.data = 2;
	nodeC.data = 3;
	nodeD.data = 4;
	nodeE.data = 5;

	nodeA.lchild = &nodeB;
	nodeA.rchild = &nodeC;
	nodeB.lchild = &nodeD;
	nodeC.lchild = &nodeE;
	
	// 非递归中序遍历
	nonRecursionInOrder(&nodeA);
	// 4 2 1 5 3
	printf("\n");

}

int main()
{
	operatorTree();

	return 0;
}


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值