中序遍历的几种情况
分析1:什么时候访问根、什么时候访问左子树、什么访问右子树
当左子树为空或者左子树已经访问完毕以后,再访问根
访问完毕根以后,再访问右子树。
分析2:为什么是栈,而不是其他队列。
先走到的后访问、后走到的先访问,显然是栈结构
分析3:结点所有路径情况
- 步骤1:
如果结点有左子树,该结点入栈;
如果结点没有左子树,访问该结点; 步骤2:
如果结点有右子树,重复步骤1;
如果结点没有右子树(结点访问完毕),回退,让栈顶元素出栈,访问栈顶元素,并访问栈顶元素的右子树,重复步骤1步骤3:
如果栈为空,表示遍历结束。
注意:入栈的结点表示,本身没有被访问过,同时右子树也没有被访问过。
/*返回的是中序遍历的起点*/
BiTNode * goLeft(BiTNode * T, stack<BiTNode*>& s)
{
if (T == NULL)//合法性检测
{
return NULL;
}
/*如果有左子树就直接入栈*/
while (T->lchild != NULL)
{
s.push(T);//入栈
T = T->lchild;//指针指向左子树
}
/*没有左子树就直接访问--返回给上层应用*/
return T;
}
void Inorder2(BiTNode * T)
{
BiTNode * t = NULL;
stack<BiTNode*> s;
t = goLeft(T, s);
while (t)
{
/*直接访问中序遍历的起点*/
printf("%d\t",t->data);
/*如果有右子树,重复步骤1*/
if (t->rchild != NULL){
t = goLeft(t->rchild, s);//右子树中中序遍历的起点
}
else if (!s.empty()){//如果没有右子树,根据栈顶元素回退
t = s.top();//更新t为下次所用
s.pop();
}//如果没有右子树,而且栈为空,表示遍历结束
else{
t = NULL;
}
}
}
- C语言版本的非递归遍历——使用自己的链式栈实现
#include "linkstack.h"
//二叉链表示法
struct _bitTree
{
int data;
struct _bitTree * lchild, *rchild;
};
typedef struct _bitTree BiTNode;
typedef struct _bitTree* BiTreee;
/*返回的是中序遍历的起点*/
BiTNode * goLeft(BiTNode * T, LinkStack* s)
{
if (T == NULL)//合法性检测
{
return NULL;
}
/*如果有左子树就直接入栈*/
while (T->lchild != NULL)
{
LinkStack_Push(s,(void*)T);//入栈
T = T->lchild;//指针指向左子树
}
/*没有左子树就直接访问--返回给上层应用*/
return T;
}
void Inorder2(BiTNode * T)
{
BiTNode * t = NULL;
LinkStack* s = LinkStack_Create();
if (s == NULL)
{
return ;
}
t = goLeft(T, s);
while (t)
{
/*直接访问中序遍历的起点*/
printf("%d\t",t->data);
/*如果有右子树,重复步骤1*/
if (t->rchild != NULL){
t = goLeft(t->rchild, s);//右子树中中序遍历的起点
}
else if (LinkStack_Size(s) > 0){//如果没有右子树,根据栈顶元素回退
t = (BiTNode*)LinkStack_Pop(s);//更新t为下次所用
//s.pop();
}//如果没有右子树,而且栈为空,表示遍历结束
else{
t = NULL;
}
}
}
/*先序遍历*/
void preOrder(BiTNode * root)
{
/*先根节点*/
if (root == NULL)
{
return;
}
printf("%d", root->data);
/*遍历左子树*/
preOrder(root->lchild);
/*遍历右子树*/
preOrder(root->rchild);
}
int main(void)
{
BiTNode t1, t2, t3, t4, t5;
memset(&t1, 0, sizeof(BiTNode));
memset(&t2, 0, sizeof(BiTNode));
memset(&t3, 0, sizeof(BiTNode));
memset(&t4, 0, sizeof(BiTNode));
memset(&t5, 0, sizeof(BiTNode));
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;
Inorder2(&t1);
//printf("%d\n",Depth(&t1));
system("pause");
return 0;
}