二叉树的中序遍历的无栈非递归算法中,需要解决的两个问题是:
1、判断子树是否已经遍历
2、从子节点回溯到父节点
要解决这两个问题可以在树的结点中增加两个数据:parent和isVisited,这样可以解决,但如果不添加新的数据结构,又如何解决呢?
可以在遍历树的结点之前将每个结点与其下一个遍历结点相关联起来,这种关联关系既可以用来回溯到父节点,也可以用来判断子树是否已经遍历。
直接上程序:
/*
*二叉树
*无栈非递归中序遍历算法
*树节点不添加新参数
*/
#include<iostream>
using namespace std;
typedef struct Node
{
int value;
Node *left;
Node *right;
Node(int val,Node *l,Node *r)
{
value=val;
left=l;
right=r;
}
}Node;
int main()
{
Node node1=Node(1,NULL,NULL);
Node node2=Node(5,NULL,NULL);
Node node3=Node(16,NULL,NULL);
Node node4=Node(21,NULL,NULL);
Node node5=Node(4,&node1,&node2);
Node node6=Node(17,&node3,&node4);
Node tree=Node(10,&node5,&node6);
Node *pNode=&tree;
while(pNode)
{
//向左走,但是对每个结点都得先向右走到极点
Node *pLeft=pNode->left;
if(pLeft)
{
//如果节点的左孩子不为空,则将该节点pNode的左孩子pLeft的最右孩子指向该节点pNode
// 以便在中序遍历的时候遍历完pLeft的最右孩子后能够跳转到pNode
//向右走,走到最右边
while(pLeft->right && pLeft->right!=pNode)
{
pLeft=pLeft->right;
}
//根据pNode的左孩子的最右节点的右指针是否为空来判断目前是在向下搜索还是
//向上回溯
if(!pLeft->right)
{//向下搜索的时候,将最右边的结点与其下一个回溯点相连
pLeft->right=pNode;
pNode=pNode->left;
continue;
}else{
//向上回溯的时候,解除指针
pLeft->right=NULL;
}
}
//左结点不存在或左子树已经遍历,则输出当前结点
cout<<pNode->value<<" ";
pNode=pNode->right;
}
cout<<endl;
return 0;
}
参考博文:
http://blog.youkuaiyun.com/quickbasic411/article/details/6968206
http://blog.youkuaiyun.com/fisher_jiang/article/details/2437714