数据结构 对于树(二叉树)的前序后序(中序)的理解

数据结构:对于代码的理解要能够用语言去表达出来,那才叫真的理解。

目前对于树的遍历只停留在知道应该怎样去遍历的阶段。

以下所有观点仅是个人看法,欢迎补充和评论,共同进步。

问题一:

树(二叉树)的前序和后序非递归遍历到底有何区别

答:

前序:先根后孩子 后序:先孩子后跟

其实,我们观察代码,可以发现,树的前序和后序(二叉树的前序和中序)的非递归代码可以非常相似,当初刚刚再网上看到这个代码时,其实我也是感到十分地惊讶。

以下代码都是使用了栈,只是一个是顺序栈,一个是链表栈

树的后序遍历的代码,借鉴与二叉树的中序遍历

void OrderLast(CTree* tree)

{

ChildPtr* stack[MAX_TREE_SIZE];

int top = -1;

ChildPtr* p;

ChildPtr* root = tree->nodes[tree->r].firstchild;

if (root == NULL)

return;

else

{

p = root;

while (top > -1||p)//栈非空

{

while (p!=NULL)//先对p的孩子进行操作

{

top++;

stack[top] = p;

p = search(tree, p->child);

}

if (top>-1)//next对于p来说是兄弟关系,所以先入栈,后输出

{

p = stack[top];

top--;

printf("%c", p->child);

p = p->next;

}

}

}

printf("%c", tree->nodes[tree->r].data);

}

二叉树的先序遍历,相当于树的先序遍历:

void Preorder(TreeNode* root)//非递归遍历

{

if (root == NULL)

return;

Stack* S = InitStack();

TreeNode* p;

p = root;

while (p)

{

visit(p);

Push(S, p);

p = p->child;

}

while (!EmptyStack(S))

{

p = Pop(S);

if (p->brother)

{

p = p->brother;

while (p)

{

visit(p);

Push(S, p);

p = p->child;

}

}

}

}

我们可以惊奇地发现,是不是除了输出的位置变化了一下,其他基本没变呢

这说明了其实对树(二叉树)来说,前序和后序(中序)其实本质上可以是相同的,即我经过每一个结点的顺序是相同的,但对于前序来说,会把数据先吐出来,在把数据存起来;二后序(中序)则会把数据存起来,等到没东西可进了在吐出来;二叉树的后序就真不太一样了,还要考虑右侧结点是否遍历过。

还有一种前序遍历的代码:

是先把右侧的结点存起来,因为栈有先进后出的特殊性,所以要先入栈,但是就其根本而言,和前面的思路其实也八九不离十,都是通过各种方式先遍历到树的最左侧叶子结点,下面这种方法只是在向左遍历的过程中顺道把右侧结点给储存起来。

void OrderFirst(CTree* tree)

{

ChildPtr* stack[MAX_TREE_SIZE];

int top = -1;

ChildPtr* p;

printf("%c", tree->nodes[tree->r].data);

ChildPtr* root = tree->nodes[tree->r].firstchild;

if (root == NULL)

return;

else

{

top++;

stack[top] = root;

while (top > -1)//栈非空

{

p = stack[top];

top--;

printf("%c", p->child);

if (p->next != NULL)//next对于p来说是兄弟关系,所以先入栈,后输出

{

top++;

stack[top] = p->next;

}

if ((p = search(tree, p->child)) != NULL)//先对p的孩子进行操作

{

top++;

stack[top] = p;

}

}

}

}

问题二:树的后序遍历为什么和对应二叉树前序遍历一致

答:对于树来说,中的概念并不好定义,比如,如果有一个结点有三个孩子,那么按照二叉树的中序,我们又该在什么时候去遍历位于“中间”的根呢。对于用二叉树表示的树来说,其所有孩子就是二叉树的左子树,所以先遍历其左子树就是先遍历了树的孩子,就是树的后序遍历了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值