目录
- 如何按层的顺序遍历二叉树
- 如何Inorder遍历二叉树
- 如何Preorder遍历二叉树
- 如何PostOrder遍历二叉树
核心思想:利用栈和队列解决非结构化数据结构的遍历
前情提要
- 树是一种什么样的数据结构(使用python实现)
- 如何在二叉树中插入node(使用python实现)
- 如何从二叉树中删除node(使用python实现)
Part 1. 如何按层的顺序遍历二叉树中每一个node
方法1. 使用for loop按层打印
1. 伪代码:printLevelOrder(tree)
for
2. 思路:从第一层开始,打印出每层的node的value
- 辅助函数:printGivenLevel ——> 打印出指定层的node的value
- 需要参数:d ——> 树的高度
3. python3实现
# A node structure
class Node:
# A utility function to create a new node
def __init__(self, key):
self.data = key
self.left = None
self.right = None
# Function to print level order traversal of tree
def printLevelOrder(root):
h = height(root) # get the height of the tree
for i in range(1, h+1): # loop the height and print the root
printGivenLevel(root, i)
# Print the node at a given level
def printGivenLevel(root, level):
if root is None:
return
if level == 1:
print(root.data, end=" ")
elif level > 1:
printGivenLevel(root.left, level-1)
printGivenLevel(root.right, level-1)
# Compute the height of the tree
def height(node):
if node is None:
return 0
else:
lheight = height(node.left)
rheight = height(node.right)
if lheight > rheight:
return lheight + 1
else:
return rheight + 1
# Drive the program
if __name__ == '__main__':
root = Node(10)
root.left = Node(11)
root.left.left = Node(7)
root.left.right = Node(12)
root.right = Node(9)
root.right.left = Node(15)
root.right.right = Node(8)
# printGivenLevel(root, 2)
# printLevelOrder(root)
该方法的时间复杂度为O(n**2),因为使用了两层loop循环
方法2. 使用队列
- 伪代码
printLevelOrder(tree)
1) Create an empty queue q
2) temp_node = root / *start from root*/
3) Loop while temp_node is not null
a) print temp_node.data
b) Enqueue temp_node's children (first left then right) to q
c) Dequeue a node from q and assign it's value to temp_node
2. 思路
- 创建一个队列:q
- 创建一个临时node:temp_node
- 利用队列控制打印顺序
队列顺序:
round1:
- temp_node -> [ node(8) ]
- print( node(8).value )
- q = [ node(8).left_node, node(8).right_node ]
- temp_node = node(4), q = [ node(12) ]
round2:
- temp_node is not null
- print( node(4).value )
- q = [ node(12), node(4).left, node(4).right ]
- temp_node = node(12), q = [ node(2), node(6) ]
... ...
# Python program to print level order traversal using Queue
# A node structure
class Node:
def __init__(self, key):
self.data = key
self.left = None
self.right = None
# Iterative Method to print the node in level order
def printLevelOrder(root):
# Base case
if root is None:
return
# Create an empty queue
queue = []
# Enqueue the root for initialize
queue.append(root)
while (len(queue) > 0):
# print the front of queue and remove it from queue
print(queue[0].data)
temp_node = queue.pop(0)
# Enqueue left child
if temp_node.left is not None:
queue.append(temp_node.left)
# Enqueue right child
if temp_node.right is not None:
queue.append(temp_node.right)
# Drive the code
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
print("Level order Traversal of binary tree is - ")
printLevelOrder(root)
Part 2. 如何inorder遍历二叉树
- 什么是Inorder
- go to left-subtree
- visit node
- go to right-subtree
2. 伪代码
1) Create an empty queue Q
2) Initialize current node as root
3) Append the current node to Q and set current = current.left until current is Null
4) If current is Null and queue is not empty then
a) Pop the top item from queue
b) Print the popped item, set current = pop_item.right
c) go to step 3
5) If current is Null and stack is empty then done
1
/
2 3
/
4 5
3. 思路
- 创建一个空的队列S
step1:
- [ node(4), node(2), node(1) ]
step2:
- pop(node(4))
- [ node(2), node(1) ]
- current_node = node(4).right = null
step3:
- pop(node(2))
- [ node(1) ]
- current = node(2).right = node(5)
- [ node(5), node(1) ]
... ...
# Python program to print Inorder traversal using Queue
# A node structure
class Node:
def __init__(self, key):
self.data = key
self.left = None
self.right = None
# Iterative Method to print the node in level order
def printInOrder(root):
# Base case
if root is None:
return
current = root
queue = []
done = 0
while True:
# Reach the left most Node of the current node
if current is not None:
queue.append(current)
current = current.left
elif(stack):
current = queue.pop()
print(current.data, end=" ")
current = current.right
else:
break
# Drive the code
""" Constructed binary tree is
1
/
2 3
/
4 5 """
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
inorder(root)
4. while内函数运行顺序
- if current is not None:
- elif(stack):
- if current is not None:
- elif(stack):
- ... ...
- break
Part 3. 如何Preorder遍历二叉树
- 什么是PreOrder
- visit node
- go to left-subtree
- go to right-subtree
2. 伪代码
1) Create an empty queue and append root node to stack
2) do following while queue is not empty
a) pop an item from queue and print it
b) append left child of popped item to queue
c) append right child of popped item to queue
1
/
2 3
/
4 5
2. 思路
- [ 1 ] ——> print(1)
- [ 2, 3 ] ——> print(2)
- [ 3, 4, 5 ] ——> print(3)
- [ 4, 5 ] ——> print(4)
- [ 5 ] ——> print(5)
# Python program to print Preorder order traversal using Queue
# A node structure
class Node():
def __init__(self, key):
self.data = key
self.left = None
self.right = None
def printPreorder(root):
# base case
if root is None:
return
# Create an empty queue and initialize with the root
queue = []
queue.append(root)
# a) print it
# b) append right child
# c) append left child
while (len(queue) > 0):
node = queue.pop()
print(node.data, end=" ")
if node.right is not None:
queue.append(node.right)
if node.left is not None:
queue.append(node.left)
# Drive the code
""" Constructed binary tree is
1
/
2 3
/
4 5 """
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
printPreorder(root)
Part 3. 如何PostOrder遍历二叉树
- 什么是PostOrder
- go to left-subtree
- go to right-subtree
- visit node
2. 伪代码
1.1 Create an empty queue
2.1 Do following while root is not Null
a) Append root's right child and then root to queue
b) set root to root's left child
2.2 Pop an item from queue and set it as root
a) If the popped item has a right child and the right child is at the top of stack
then remove the right child from queue
append the root back and set root as root's right child
b) Else print root's data and set root as Null
2.3 Repeat steps 2.1 and 2.2 while queue is not empty
1
/
2 3
/ /
4 5 6 7
3. 思路
1. Right child of 1 exists.
Push 3 to stack. Push 1 to stack. Move to left child.
Stack: 3, 1
2. Right child of 2 exists.
Push 5 to stack. Push 2 to stack. Move to left child.
Stack: 3, 1, 5, 2
3. Right child of 4 doesn't exist. '
Push 4 to stack. Move to left child.
Stack: 3, 1, 5, 2, 4
4. Current node is NULL.
Pop 4 from stack. Right child of 4 doesn't exist.
Print 4. Set current node to NULL.
Stack: 3, 1, 5, 2
5. Current node is NULL.
Pop 2 from stack. Since right child of 2 equals stack top element,
pop 5 from stack. Now push 2 to stack.
Move current node to right child of 2 i.e. 5
Stack: 3, 1, 2
6. Right child of 5 doesn't exist. Push 5 to stack. Move to left child.
Stack: 3, 1, 2, 5
7. Current node is NULL. Pop 5 from stack. Right child of 5 doesn't exist.
Print 5. Set current node to NULL.
Stack: 3, 1, 2
8. Current node is NULL. Pop 2 from stack.
Right child of 2 is not equal to stack top element.
Print 2. Set current node to NULL.
Stack: 3, 1
9. Current node is NULL. Pop 1 from stack.
Since right child of 1 equals stack top element, pop 3 from stack.
Now push 1 to stack. Move current node to right child of 1 i.e. 3
Stack: 1
10. Repeat the same as above steps and Print 6, 7 and 3.
Pop 1 and Print 1.
代码
# Python program for iterative postorder traversal
# using one stack
# Stores the answer
ans = []
# A Binary tree node
class Node:
# Constructor to create a new node
def __init__(self, data):
self.data = data
self.left = None
self.right = None
def peek(stack):
if len(stack) > 0:
return stack[-1]
return None
# A iterative function to do postorder traversal of
# a given binary tree
def postOrderIterative(root):
# Check for empty tree
if root is None:
return
stack = []
while(True):
while (root):
# Push root's right child and then root to stack
if root.right is not None:
stack.append(root.right)
stack.append(root)
# Set root as root's left child
root = root.left
# Pop an item from stack and set it as root
root = stack.pop()
# If the popped item has a right child and the
# right child is not processed yet, then make sure
# right child is processed before root
if (root.right is not None and
peek(stack) == root.right):
stack.pop() # Remove right child from stack
stack.append(root) # Push root back to stack
root = root.right # change root so that the
# righ childis processed next
# Else print root's data and set root as None
else:
ans.append(root.data)
root = None
if (len(stack) <= 0):
break
# Driver pogram to test above function
root = Node(1)
root.left = Node(2)
root.right = Node(3)
root.left.left = Node(4)
root.left.right = Node(5)
root.right.left = Node(6)
root.right.right = Node(7)
print ("Post Order traversal of binary tree is")
postOrderIterative(root)