数据结构二叉树的建立与遍历完整代码_【数据结构与算法】(4)可视化解析二叉树的四种遍历...

6a4478a0197cb31ceb29df2d9c6047e4.png

目录

  1. 如何按层的顺序遍历二叉树
  2. 如何Inorder遍历二叉树
  3. 如何Preorder遍历二叉树
  4. 如何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)

c625b01dde6a1ee05293a65bcb964bfe.png
printGivenLevel(root, 2)

b326a47e580d8ef819d98cfd9a74d4e6.png
printLevelOrder(root)

该方法的时间复杂度为O(n**2),因为使用了两层loop循环


方法2. 使用队列

  1. 伪代码
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
  • 利用队列控制打印顺序

00656d2fce014d7bb892a832351fbbdc.png

队列顺序:

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)

bfba5b9baec46937fd936a19550cf7c4.png

Part 2. 如何inorder遍历二叉树

  1. 什么是Inorder
  • go to left-subtree
  • visit node
  • go to right-subtree

efbd7e62e7b32fc0b282c57d9cf92972.gif
inorder遍历二叉树

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)

df08b2e76c08d28a3be23ce279451e2c.png

4. while内函数运行顺序

  • if current is not None:
  • elif(stack):
  • if current is not None:
  • elif(stack):
  • ... ...
  • break

Part 3. 如何Preorder遍历二叉树

  1. 什么是PreOrder
  • visit node
  • go to left-subtree
  • go to right-subtree

63053d14af031bd4c158210084235d92.gif
preorder遍历二叉树

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)

7ad7d045108dfeafc75262ef27ae267a.png

Part 3. 如何PostOrder遍历二叉树

  1. 什么是PostOrder
  • go to left-subtree
  • go to right-subtree
  • visit node

de839071beccb2c37a57dbbb074388f9.gif
postorder遍历二叉树

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) 

b774a9d8bf234b0f03c91dd5b0aeb475.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值