后序遍历

369 阅读2分钟

前面说了前序遍历。中序遍历和前序遍历一样,就是把访问节点值的位置挪挪地方而已。

中序遍历

中序遍历和前序遍历需要用到栈保存访问过的节点的原因是:

前序遍历是先访问中间节点,再访问左子树,再访问右子树。

因为访问左子树是一个递归的操作,递归如果用非递归形式实现就是循环,也就是说访问左子树是一个循环操作。

它跟访问中间节点不一样,在一次循环中无法完成,因为要到之后才能完成,所以得保存下来。

并且由于访问中间节点不是循环操作,在一次循环中就能完成,所以在递归左子树之前访问一下中间节点就可以了,左子树访问过的,中间节点就一定也访问过了。它们的状态是一致的。

中序遍历也是一样的。

这个栈中保存的就是接下来需要处理右子树的节点。

后序遍历

但是后序遍历就有点不一样了:

先访问左子树,再访问右子树,再访问中间节点。它也需要栈来保存访问状态,但是左子树已经访问过的节点,它的右子树不一定访问过了,中间节点也不一样访问过了,右子树和中间节点的访问状态也不一定一致,所以一个栈就无法保存下来需要的状态。那就需要两个栈了。

这个还是有点复杂啰嗦的。

后来在网上发现一种极为巧妙的办法,让人拍案叫绝!

后序遍历的精妙办法

后序遍历(左右中)的结果是:1325764

那逆后序遍历(中右左)结果就是:4675231

中右左也就是前序遍历时先访问右子树,再访问左子树,这就很容易了

所以:

  1. 中右左的方式前序遍历
  2. 把 1 中得到的结果逆序一遍,得到的就是后序遍历了