1. Depth First Search(DFS)
其过程简要来说就是对每一个可能的分支路径深入到不能深入为止,而且每个节点只能访问一次。
对于上面的例子,DFS的结果就是A,B,D,E,I,C,F,G,H.(假设先走子节点的的左侧)。
深度优先搜索遍历各个节点,需要使用栈的数据结构,其特点是后进先出。整个遍历过程如下:
1)首先将A节点压入栈中,stack(A);
2)将A节点弹出,同时将A节点的C、B压入栈中,此时B在栈的顶部,stack(C,B);
3)将B节点弹出,同时将B的子节点E、D压入栈中,此时D在栈的顶部,stack(C,E,D);
4)将D节点弹出,D没有子节点,此时E在栈的顶部,stack(C,E);
5)将E节点弹出,同时将E的子节点I压入,stack(C,I);
......依次往下,最终遍历完成。
python代码:
# -*- coding: utf-8 -*-
class TreeNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
class Tree_Method:
def create_tree(self, arr):
'''
利用二叉树的三个组成部分:根节点-左子树-右子树;
传入的arr是一个多维列表,每一维最大为3,
每一维中的内容依次表示根节点-左子树-右子树。然后递归的进行构建
'''
length = len(arr) #计算每一维的大小
root = TreeNode(arr[0]) #获取每一维的根节点
if length >= 2: #判断是否有左子树
root.left = self.create_tree(arr[1])
if length >= 3: #判断是否有右子树
root.right = self.create_tree(arr[2])
return root
def DFS(self, root):
'''
深度优先遍历,即先访问根节点,然后遍历左子树接着遍历右子树。
主要利用栈的特点,先将右子树压栈,再将左子树压栈,这样左子树就位于栈顶,
可以结点的左子树先与右子树被遍历。
'''
if root == None:
return None
stack = []
'''用列表模仿入栈'''
stack.append(root)
while stack:
'''将栈顶元素出栈'''
current_node = stack.pop()
print(current_node.value, end=' ')
'''判断该节点是否有右孩子,有就入栈'''
if current_node.right:
stack.append(current_node.right)
'''判断该节点是否有左孩子,有就入栈'''
if current_node.left:
stack.append(current_node.left)
if __name__ == '__main__':
arr = [2,[3,[4],[5]],[2,[4,[7]],[3]]]
op = Tree_Method()
tree = op.create_tree(arr)
print('深度优先遍历:', end='')
op.DFS(tree)
!!!DFS对于树来说就是前序遍历,中序遍历,后序遍历!!!
# -*- coding: utf-8 -*-
class TreeNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
def preOrder(self, root):
'''先序遍历'''
if root == None:
return None
print(root.value)
self.preOrder(root.left)
self.preOrder(root.right)
def minOrder(self, root):
'''中序遍历'''
if root == None:
return None
self.minOrder(root.left)
print(root.value)
self.minOrder(root.right)
def postOrder(self, root):
'''后序遍历'''
if root == None:
return None
self.postOrder(root.left)
self.postOrder(root.right)
print(root.value)
2. Breadth First Search(BFS)
!!!BFS对于树来说就是层次遍历!!!
其过程简单来说是对每一层节点依次访问,访问完一层进入下一层,而且每个节点只能访问一次。
对于上面的例子,BFS的结果就是A,B,C,D,E,F,G,H,I(假设每层节点从左到右访问)。
广度优先遍历各个节点,需要使用队列(Queue)这种数据结构,其特点是先进先出。也可以使用双端队列,区别就是双端队列首尾都可以插入和弹出节点。整个遍历过程如下:
1)首先将A节点插入队列中,queue(A);
2)将A节点弹出,同时将A的子结点B、C插入队列中,此时B在队列首部,C在队列尾部,queue(B,C);
3)将B节点弹出,同时将B的子结点D、E插入队列中,此时C在队列首部,E在队列尾部,queue(C,D,E);
4)将C节点弹出,同时将C的子节点F,G,H插入队列中,此时D在队列首部,H在队列尾部,queue(D,E,F,G,H);
5)将D节点弹出,D没有子节点,此时E在队列首部,H在队列尾部,queue(E,F,G,H);
.......依次往下,最终遍历完成。
python代码:
# -*- coding: utf-8 -*-
class TreeNode:
def __init__(self, value):
self.value = value
self.left = None
self.right = None
class Tree_Method:
def create_tree(self, arr):
'''
利用二叉树的三个组成部分:根节点-左子树-右子树;
传入的arr是一个多维列表,每一维最大为3,
每一维中的内容依次表示根节点-左子树-右子树。然后递归的进行构建
'''
length = len(arr) #计算每一维的大小
root = TreeNode(arr[0]) #获取每一维的根节点
if length >= 2: #判断是否有左子树
root.left = self.create_tree(arr[1])
if length >= 3: #判断是否有右子树
root.right = self.create_tree(arr[2])
return root
def BFS(self, root):
'''
广度优先遍历,即从上到下,从左到右遍历。
主要利用队列先进先出的特性,入队的时候,是按根左右的顺序,那么只要按照这个顺序出队就可以了
'''
if root == None:
return None
queue = []
'''用列表模仿入队'''
queue.append(root)
while queue:
'''将队首元素出栈'''
current_node = queue.pop(0)
print(current_node.value, end=' ')
'''判断该节点是否有左孩子,有就入队'''
if current_node.left:
queue.append(current_node.left)
'''判断该节点是否有右孩子,有就入队'''
if current_node.right:
queue.append(current_node.right)
if __name__ == '__main__':
arr = [2,[3,[4],[5]],[2,[4,[7]],[3]]]
op = Tree_Method()
tree = op.create_tree(arr)
print('广度优先遍历:', end='')
op.BFS(tree)