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

中序 遍历的几种情况

分析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;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-25 19:45:13

树的非递归遍历(中序遍历)的相关文章

[C++]LeetCode: 93 Binary Search Tree Iterator (经典题,非递归的中序遍历)

题目: Implement an iterator over a binary search tree (BST). Your iterator will be initialized with the root node of a BST. Calling next() will return the next smallest number in the BST. Note: next() and hasNext() should run in average O(1) time and u

非递归实现先序遍历 java leecode 提交

写完才知道自己学习都是似是而非啊,大家可以也在leecode上提交代码,纯手写,离开eclipse第一种方式:数据结构书上的,使用栈大概思路.1.不断将根节点的左孩子的左孩子直到为空,在这个过程入栈.2.因为栈顶的节点的左孩子为空,所以栈顶的的节点的左子树肯定访问完毕,所以出栈后直接指向右孩子.其实这里面有个思想迭代和递归的本质相同之处是什么?以后会写一篇我的思考. public class Solution { public List<Integer> preorderTraversal(T

根据先序遍历中序遍历重建二叉树

根据先序遍历和中序遍历的特点,我们想到了采用递归的方法来实现. 思路:1) 代码的容错性检查,比如:先序遍历和中序遍历长度应相等 2) 先保存先序遍历的第一个点,这个点为结点,接下来循环中序遍历,直到midOrd[index]=该结点,那么接下来就可以采用递归,分别对结点左边和右边的序列采用相同的方法. 3) 直到中序遍历中的序列中只含一个点,整个过程结束. 下面是我写的代码,一直显示错误,不知道什么原因. // 先序中序重建二叉树.cpp : Defines the entry point f

前序遍历 中序遍历 后序遍历

前序遍历(DLR) 前序遍历也叫做先根遍历.先序遍历,可记做根左右. 前序遍历首先访问根结点然后遍历左子树,最后遍历右子树.在遍历左.右子树时,仍然先访问根结点,然后遍历左子树,最后遍历右子树. 若二叉树为空则结束返回,否则: (1)访问根结点. (2)前序遍历左子树. (3)前序遍历右子树 . 需要注意的是:遍历左右子树时仍然采用前序遍历方法. 如右图所示二叉树 前序遍历,也叫先根遍历,遍历的顺序是,根,左子树,右子树 遍历结果:ABDECF 中序遍历,也叫中根遍历,顺序是 左子树,根,右子树

简单的二叉树的创建(前序输入)&amp;前序遍历&amp;中序遍历&amp;后序遍历

#include <stdio.h> #include <stdlib.h> #define MAX 1024 typedef struct bitnode { int data; struct bitnode *lchild; struct bitnode *rchild; }BinTree; BinTree *Creat_Bintree() { BinTree *p; int x; scanf("%d",&x); if(x==0) { p = NUL

二叉树先序遍历中序遍历求后序遍历

先序遍历:根 左 右 中序遍历:左 根 右 后序遍历:左 右 根 我们可以先从先序遍历中找到根节点,由于知道了根节点那么可以依靠中序遍历找到左子树,右子树.这样再去先序遍历中找到左子树的根节点,然后再依靠中序遍历找到左子树的左子树(右子树同理).这样层层递归就能还原二叉树.之后求出后序遍历. 感谢原博主http://www.cnblogs.com/rain-lei/p/3576796.html 一开始递归不会写,看了博主的发现其实很简单.注意还原二叉树时return root. #include

二叉树前序遍历+中序遍历-&gt;后序遍历

BNU的基础题,数据结构的基础题,顺便搞下. 二叉树是一种常用的数据结构.我们可以用大写的英文字母表示二叉树的节点. 如下: B / \ / \ C A D 对于二叉树,有前序.中序和后序三种遍历方式. 现在给你一棵二叉树的前序和中序遍历,请你求出这棵二叉树的后序遍历结果. Input 输入数据有多组,每组数据一行. 每行由两个字符串组成(每个字符串长度最大为26).表示一棵二叉树的前序和中序遍历结果. 题目保证前序和中序遍历是合法的(即肯定可以确定一棵二叉树). Output 对于每组输入,输

LeetCode-重建二叉树(前序遍历+中序遍历)

重建二叉树 LeetCode-105 首次需要知道前序遍历和中序遍历的性质. 解题思路如下:首先使用前序比遍历找到根节点,然后使用中序遍历找到左右子树的范围,再分别对左右子树实施递归重建. 本题的难点就是如何在前序遍历中找到左右子树的范围以分别重构,这可以根据中序遍历中的左右子树的数量来分辨.使用前序遍历的根节点和中序遍历的根节点相同时,表示此时前序遍历的左子树已经找到了. 具体的实施时需要带有4个参数分别控制左右子树的范围. /** * 输入某二叉树的前序遍历和中序遍历的结果,请重建该二叉树.

二叉树遍历规则,先顺遍历/中序遍历/后序遍历

二叉树三种遍历方式 先序遍历:遍历顺序规则为[根左右] 先访问根节点,在左叶子,右叶子 中序遍历:遍历顺序规则为[左根右] 后序遍历:遍历顺序规则为[左右根] 例题 先序遍历:ABCDEFGHK 中序遍历:BDCAEHGKF 后序遍历:DCBHKGFEA 以中序遍历为例: 中序遍历的规则是[左根右],我们从root节点A看起: 此时A是根节点,遍历A的左子树: A的左子树存在,找到B,此时B看做根节点,遍历B的左子树: B的左子树不存在,返回B,根据[左根右]的遍历规则,记录B,遍历B的右子树: