中序遍历的几种情况:
分析1:什么时候访问根,什么时候访问左子树,什么访问右子树。
当左子树为空或左子树已经访问完毕以后,再访问根。
访问完毕根以后,再访问右子树。
分析2:为什么是栈,而不是其他(比如说是队列)
先走到的后访问,后走到的先访问,显然是栈结构
分析3:结点所有路径情况
步骤1:
如果结点有左子树,该结点入栈;
如果结点没有左子树,访问该结点;
步骤2:
如果结点有右子树,重复步骤1;
如果结点没有右子树(结点访问完毕),根据栈顶指示回退,并访问右子树,重复步骤1
如果栈为空,表示遍历结束。
// 中序遍历—非递归.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <iostream>
#include <algorithm>
#include <stack>
using namespace std;
struct BTNode{//树的定义
int data;
struct BTNode *lchild, *rchild;
};
typedef struct BTNode BTnode;
typedef struct BTNode* BiTree;
//一直往左走,找到中序遍历的起点
BTNode *goLeft(BTNode *T, stack<BTNode *> &s){
if (T == NULL){
return NULL;
}
while (T->lchild){//如果有左子树,入栈;如果没有左孩子
s.push(T);
T = T->lchild;
}
return T;
}
void Inorder2(BTNode *T){
//树的遍历
BTNode *t = NULL;
stack<BTNode *> s;
t=goLeft(T, s);
while (t){
printf("%d",t->data);//打印数据
if (t->rchild)//如果t有右子树,重复步骤1;
{
goLeft(t->rchild,s);//右子树中又找到中序遍历的起点
}
else if(!s.empty()){//如果t没有右子树,并且栈不为空,根据栈顶指示回退
t = s.top();//取出栈顶元素
s.pop();//弹出去
}
else{//如果t没有右子树,根据栈顶为空;
t = NULL;
}
}
}
void inOrder(BTNode *root){//中序遍历
if (root == NULL){
return;
}
//遍历左子树
inOrder(root->lchild);
printf("%d", root->data);
//遍历右子树
inOrder(root->rchild);
}
int _tmain(int argc, _TCHAR* argv[])
{
BTNode t1, t2, t3, t4, t5;
memset(&t1, 0, sizeof(BTNode));
memset(&t2, 0, sizeof(BTNode));
memset(&t3, 0, sizeof(BTNode));
memset(&t4, 0, sizeof(BTNode));
memset(&t5, 0, sizeof(BTNode));
t1.data = 1;
t2.data = 2;
t3.data = 3;
t4.data = 4;
t5.data = 5;
//建立关系
t1.lchild = &t2;
t1.rchild = &t3;
t2.lchild = &t4;
t3.lchild = &t5;
inOrder(&t1);//非递归中序遍历
return 0;
}