中序 遍历的几种情况
分析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;
}