Python 实现二叉树的各种遍历
假设有这么一个二叉树如下:
根据上述的二叉树,可以计算到:
前序遍历结果:1, 2, 4, 5, 8, 9, 11, 3, 6, 7, 10
中序遍历结果:4, 2, 8, 5, 11, 9, 1, 6, 3, 10, 7
后序遍历结果:4, 8, 11, 9, 5, 2, 6, 10, 7, 3, 1
二叉树的类实现
深度优先遍历
递归实现
非递归实现
前序遍历
根据已有的认识,此函数需要一个栈,保存树尚未访问过的部分信息。对于前序遍历也会有不同的实现方法,下面考虑一种方法,即:
由于采取先序遍历,遇到结点就应该访问,下一步就应该沿着树的坐分支下行
但结点的右分支(右子树)还没有访问,因此需要记录,将右子结点入栈。
遇到空树时回溯,取出栈中保存的一个右分支,像一颗二叉树一样遍历它。
非递归算法的一个价值是把算法过程完整的暴露出来,便于进行细致的分析。
时间复杂度:在非递归的算法中,因为在执行的过程中访问每个结点一次,一部分子树(所有右子树,方法一、二)被压入和弹出各一次(栈操作是O(1)时间),所以整个遍历过程需要的时间复杂度为O(n)。
空间复杂度:这里的关键因素是遍历中栈可能达到的最大深度(栈中元素的最大深度个数),而栈的最大深度由被遍历的二叉树的高度决定。由于二叉树的高度可能达到O(n),所以在最坏情况下,算法的空间复杂度为O(n),n个结点的二叉树的平均高度为O(log n),所以非递归前序遍历的平均空间复杂度为O(log n)。
在一些情况下,修改实现方法也可能降低空间的开销。对于上面函数,修改其定义,只把非空的右子树进栈,在很多情况下能减小一些空间开销。
其他非递归的遍历算法,包括中序遍历和后续遍历算法以及层次遍历算法,都可以直接了当的修改成迭代器。但是递归算法不可以。
中序遍历
后序遍历
广度优先遍历
版权声明: 本文为 InfoQ 作者【王坤祥】的原创文章。
原文链接:【http://xie.infoq.cn/article/fca273228162061ff76c19d3f】。
本文遵守【CC BY-NC】协议,转载请保留原文出处及本版权声明。
评论