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

算法:

 

#include <iostream>
#include <stack>
using namespace std;
/*
	二叉树的遍历---中序遍历非递归算法
	中序 遍历的几种情况
	分析1:什么时候访问根、什么时候访问左子树、什么访问右子树
		当左子树为空或者左子树已经访问完毕以后,再访问根
		访问完毕根以后,再访问右子树。
	
	分析2:为什么是栈,而不是其他队列。
		先走到的后访问,后走到的先访问,显然是栈结构
	
	分析3:结点所有路径情况
		步骤1:
			如果结点有左子树,该结点入栈;
			如果结点没有左子树,访问该结点;
		步骤2:
			如果结点有右子树,重复步骤1;
			如果结点没有右子树(结点访问完毕),根据栈顶指示回退,访问栈顶元素,并访问右子树,重复步骤1
			如果栈为空,表示遍历结束。
	
	注意:入栈的结点表示,本身没有被访问过,同时右子树也没有被访问过。
	
	分析4:有一个一直往左走入栈的操作
*/

//二叉链表
typedef struct BiNode{
	int data;
	struct BiNode *lchild, *rchild;
}BiNode, *BiTree;

#if 1
//找到向左走,找到中序遍历的起点
BiNode *goLeft(BiNode *T, stack<BiNode*> &s)
{
	if (T == NULL){
		return NULL;
	}
	//判断T有没有左孩子, 没有把T return ;
	//如果有 T入栈 ,再往左走
	while (T->lchild != NULL){
		s.push(T);
		T = T->lchild;
	}
	return T;
}

void inorder2(BiNode *T)
{
	BiNode *t = NULL;
	stack<BiNode *> s;
	t = goLeft(T, s);					//如果结点有左子树, 该结点入栈;

	while (t){
		printf("%d ", t->data);			//如果结点没有左子树,访问该结点(就是打印该节点);
		//如果 t有右子树 重复步骤1
		if (t->rchild != NULL){
			t = goLeft(t->rchild, s);	//右子树中中序遍历的起点
		}
		else if (!s.empty()){	//如果t没有右子树 根据栈顶指示 回退
			t = s.top();				//获取栈顶元素
			s.pop();					//将栈顶元素弹出
		}
		else{	//如果t没有右子树 并且栈为空,表示遍历结束
			t = NULL;
		}
	}
}

//中序遍历 左根右 Middle order traversal
void inOrder(BiNode *root)
{
	if (root == NULL){
		return;
	}
	//遍历左子树
	inOrder(root->lchild);
	printf("%d ", root->data);//打印根
	//遍历右子树
	inOrder(root->rchild);
}

/*
			t1
		  /    \
		t2		t3
		/       /
	  t4	   t5
*/
void test()
{
	BiNode t1, t2, t3, t4, t5;

	memset(&t1, 0, sizeof(BiNode));
	memset(&t2, 0, sizeof(BiNode));
	memset(&t3, 0, sizeof(BiNode));
	memset(&t4, 0, sizeof(BiNode));
	memset(&t5, 0, sizeof(BiNode));

	t1.data = 1;
	t2.data = 2;
	t3.data = 3;
	t4.data = 4;
	t5.data = 5;

	//建立树关系
	t1.lchild = &t2;	//t1的左孩子为t2
	t1.rchild = &t3;	//t1的右孩子为t3
	t2.lchild = &t4;	//t2的左孩子为t4
	t3.lchild = &t5;	//t3的左孩子为t5

	printf("\n 中序遍历 inorder\n");
	inOrder(&t1);

	printf("\n\n 中序遍历 使用非递归算法\n");
	inorder2(&t1);
}
#endif

int main()
{
	test();
	printf("\n---------hello\n");
	system("pause");
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值