题目
/****
【题目】假设在三叉链表的结点中增设一个标志域
(mark取值0,1或2)以区分在遍历过程中到达该结点
时应继续向左或向右或访问该结点。试以此存储结
构编写不用栈辅助的二叉树非递归后序遍历算法。
带标志域的三叉链表类型定义:
typedef struct TriTNode {
TElemType data;
struct TriTNode *lchild, *rchild, *parent;
int mark; // 标志域
} TriTNode, *TriTree;
****/
解题思路
- 找到子树最先开始遍历的节点,也就是整个树中最左下角的节点
- 访问这整个子树最先访问的节点。
- 回到父节点,此式父节点的右节点是第二访问的节点。
- 如果这个父节点没有右子树,或者右子树已经访问过了,则访问自身,并且返回上一个父节点。
- 通过上面已经确定这个父节点有右子树了,则重新导向他的右子树。
代码
void PostOrder(TriTree T, void (*visit)(TElemType))
/* 不使用栈,非递归后序遍历二叉树T, */
/* 对每个结点的元素域data调用函数visit */
{
TriTree p,pr;
p = T;
while(p)
{
if(p->lchild) //找到最左下角的节点
p = p->lchild;
else
{
if(p->rchild) //如果左下角的节点如果有右节点
p = p->rchild;
else
{
visit(p->data); //访问第一个需要访问的节点
p->mark = 1;
p = p->parent; //返回父节点
while(p && (p->rchild == NULL || p->rchild->mark == 1)) //如果右节点已经访问完毕或者没有右节点
{
visit(p->data);
p->mark = 1;
p = p->parent;
}
if(p) //经过上面的循环,确定当前节点一定含有右节点,访问右子树
p = p->rchild;
}
}
}
}