二叉树的前序,中序,后续,递归及非递归遍历的python实现
2018-02-21 14:35
537 查看
在计算机科学里,树的遍历(也称为树的搜索)是图的遍历的一种,指的是按照某种规则,不重复地访问某种树的所有节点的过程。具体的访问操作可能是检查节点的值、更新节点的值等。不同的遍历方式,其访问节点的顺序是不一样的。
深度优先遍历又可分为,前序遍历(pre-order), 中序遍历(in-order),后序遍历(post-order)
对于广度优先而言,遍历没有前序中序后序之分:给定一组已排序的子节点,其“广度优先”的遍历只有一种唯一的结果。
二叉树的递归算法相对简单,非递归算法实现要用到辅助栈,算法设计非常巧妙。
定义二叉树结构如下
递归写法
非递归写法
preOrder每次都将遇到的节点压入栈,当左子树遍历完毕后才从栈中弹出最后一个访问的节点,再访问其右子树。
递归写法
非递归写法
中序的非递归遍历与先序的非递归遍历类似。先序遍历是先访问节点,然后再将节点入栈,后中序遍历则是先入栈,然后节点弹出栈后再访问。
递归写法:
非递归写法:
从直觉上来说,后序遍历对比中序遍历难度要增大很多。因为中序遍历节点序列有一点的连续性,而后续遍历则感觉有一定的跳跃性。先左,再右,最后才中间节点;访问左子树后,需要跳转到右子树,右子树访问完毕了再回溯至根节点并访问之,代码如下:
可以利用队列实现广度优先搜索。
遍历的种类
遍历方式的命名,源于其访问节点的顺序。最简单的划分:深度优先,广度优先。深度优先遍历又可分为,前序遍历(pre-order), 中序遍历(in-order),后序遍历(post-order)
对于广度优先而言,遍历没有前序中序后序之分:给定一组已排序的子节点,其“广度优先”的遍历只有一种唯一的结果。
二叉树的递归算法相对简单,非递归算法实现要用到辅助栈,算法设计非常巧妙。
定义二叉树结构如下
class BinNode(): def __init__(self, val): self.left = None self.right = None self.val = val
前序遍历(pre-order)
访问顺序:根左右递归写法
def preOrder(sellf, root): if root == None: return print(root.val) self.preOrder(root.left) self.preOrder(root.right)
非递归写法
preOrder每次都将遇到的节点压入栈,当左子树遍历完毕后才从栈中弹出最后一个访问的节点,再访问其右子树。
def preOrder(self, root): if root == None: return stack = [] node = root while node or stack: while node: # 从根节点开始,一直找它的左子树 print(node.val) stack.append(node) node = node.left # while结束表示当前节点node为空,即前一个节点没有左子树了 node = stack.pop() # 开始查看它的右子树 node = node.right
中序遍历(In-order)
访问顺序:左根右递归写法
def inOrder(self, root): if root == None: return self.inOrder(root.left) print(root.val) self.inOrder(root.right)
非递归写法
中序的非递归遍历与先序的非递归遍历类似。先序遍历是先访问节点,然后再将节点入栈,后中序遍历则是先入栈,然后节点弹出栈后再访问。
def inOrder(self,root): if root == None: return stack = [] while node or stack: while node: # 从根节点开始,一直找到左子树 stack.append(node) node = node.left # while结束表示当前节点node为空,即前一个节点没有左子树了 node = stack.pop() print(node.val) node = node.right
后序遍历
访问顺序:左右根递归写法:
def postOrder(self,root): if root == None: return self.postOrder(root.left) self.postOrder(root.right) print(root.val)
非递归写法:
从直觉上来说,后序遍历对比中序遍历难度要增大很多。因为中序遍历节点序列有一点的连续性,而后续遍历则感觉有一定的跳跃性。先左,再右,最后才中间节点;访问左子树后,需要跳转到右子树,右子树访问完毕了再回溯至根节点并访问之,代码如下:
def postOrder(self,root): if root == None: return stack1 = [] stack2 = [] node = root stack1.append(node) while stack1: # 这个while循环用户找到后续遍历的逆序,存在stack2中 node = stack1.pop() if node.left: stack1.append(node.left) if node.right: stack1.append(node.right) stack2.append(node) while stack2: print(stack2.pop().val)
广度优先遍历
广度优先搜索(Breadth First Search),又叫宽度优先搜索或横向优先搜索,是从根结点开始沿着树的宽度搜索遍历。可以利用队列实现广度优先搜索。
广度优先遍历q与深度优先遍历的区别
广度优先遍历与深度优先遍历的区别在于:广度优先遍历是以层为顺序,将某一层上的所有节点都搜索到了之后才向下一层搜索;而深度优先遍历是将某一条枝桠上的所有节点都搜索到了之后,才转向搜索另一条枝桠上的所有节点。from collections import deque def BFS(self, root): if root == None: return quene = deque() node = root quene.append(node) while quene: node = quene.popleft() print(node.val) if node.left: quene.append(node.left) if node.right: quene.append(node.right)
相关文章推荐
- 递归和非递归俩种方法实现二叉树的前序、中序、后续遍历
- 二叉树(前序,中序,后序,层序)遍历递归与循环的python实现
- 用非递归实现二叉树的前序、中序、后序、层次遍历,用递归实现查找、统计个数、比较、求深度
- 二叉树前序、中序、后续遍历(递归实现)
- 二叉树前序,中序,后序的遍历【递归(借用栈实现)和非递归】
- 【python中二叉树的实现】python中二叉树的创建、三种方式递归遍历和非递归遍历
- 二叉树的前序、中序、后续遍历,递归、非递归实现
- 二叉树先序、中序、后续遍历(非递归实现)
- 二叉树的建树、遍历(先序、中序、后序、层次)(递归和非递归)--Java实现
- 二叉树的创建 先序 中序 后续 递归和非递归遍历
- python实现二叉树的建立以及遍历(递归前序、中序、后序遍历,队栈前序、中序、后序、层次遍历)
- 二叉树前序,中序,后续遍历(递归和非递归)
- Java 二叉树的前序、中序、后续遍历 递归和迭代实现
- 二叉树先序、中序、后续遍历递归以及非递归java实现
- c++实现二叉树的非递归创建以及非递归先序、中序、后序遍历
- 二叉树的实现&&递归和非递归方式前序、中序、后续遍历&&发现一个节点中序遍历的下一节点
- java语言实现二叉树的前序、中序与后序遍历(递归与非递归) 层次遍历
- java实现的二叉树(前序、中序、后序)递归和非递归遍历,包含层序遍历
- java语言实现二叉树的前序、中序与后序遍历(递归与非递归)
- 数据结构---二叉树的前序、中序、后序遍历的递归和非递归 实现(C++)