您的位置:首页 > 编程语言 > Python开发

二叉树的前序,中序,后续,递归及非递归遍历的python实现

2018-02-21 14:35 537 查看
在计算机科学里,树的遍历(也称为树的搜索)是图的遍历的一种,指的是按照某种规则,不重复地访问某种树的所有节点的过程。具体的访问操作可能是检查节点的值、更新节点的值等。不同的遍历方式,其访问节点的顺序是不一样的。

遍历的种类

遍历方式的命名,源于其访问节点的顺序。最简单的划分:深度优先,广度优先。

深度优先遍历又可分为,前序遍历(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)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐