(二叉树采用三叉链表的存储结构,编写
不借助栈的非递归中序遍历算法)
三叉链表类型定义:
typedef struct TriTNode {
TElemType data;
struct TriTNode *parent, *lchild, *rchild;
} TriTNode, *TriTree;
思路为:1 先向左走到尽头,访问了最左结点
2 判断是否有右结点,若有(遍历完右子树再上去p->parent){
p指向p->rchild,回到上代码最上,判断p是否有左结点
}
若无,{
pre指向p,p指向parent,访问parent(访问条件,必须是从左子树上来的才访问,右子树上来不访问p->lchild == pre时访问)
}
3 在访问了parent结点后,
(1)parent无右结点,再向上走,继续访问
(2)parent有右结点,指向右结点,回到代码头
void InOrder(TriTree PT, void (visit)(TElemType))
/ 不使用栈,非递归中序遍历二叉树PT, /
/ 对每个结点的元素域data调用函数visit */
{
TriTree p = PT;
TriTree pre = NULL;
while(p != NULL){
while(p -> lchild != NULL){
p = p -> lchild;
}
//当左子树空的时候
if( p ) {
visit(p -> data);
}
//遍历完本节点,左子树一定已经遍历过了,所以此时考虑是否往右走,右子树不为空的话,一定要往右边走
if(p -> rchild != NULL){
p = p->rchild;
}
else{
//如果右子树为空,且此时左子树已经遍历,便要往上走
//第二种往上走的情况是遍历完右子树
do{
pre = p;
p = p->parent;
if( p && p->lchild == pre) {
visit(p -> data);
}
}while((p->lchild == pre && p -> rchild == NULL) || p->rchild == pre);
//这里往右边走是遍历完左子树后
if(pre == p->lchild && p -> rchild != NULL){
p = p->rchild;
}
}
}
}