二叉树的先序遍历、中序遍历、后续遍历(采用递归和栈两种)层序遍历(使用队列)

首先我们要先自己建立一个二叉树,我们先根据我自己随便写的二叉树建立一个列表保存二叉树的各个节点的信息,当然你也可以直接写个程序自己建立。

node_list = [
    {'data':'A', 'left':'B', 'right':'C', 'is_root':True},
    {'data':'B', 'left':'D', 'right':'E', 'is_root':False},
    {'data':'C', 'left':'F', 'right':'G', 'is_root':False},
    {'data':'D', 'left':None, 'right':None, 'is_root':False},
    {'data':'E', 'left':'H', 'right':None, 'is_root':False},
    {'data':'H', 'left':None, 'right':None, 'is_root':False},
    {'data':'F', 'left':None, 'right':None, 'is_root':False},
    {'data':'G', 'left':'I', 'right':'J', 'is_root':False},
    {'data':'I', 'left':None, 'right':None, 'is_root':False},
    {'data':'J', 'left':None, 'right':None, 'is_root':False}
]

然后根据建的列表建立一个二叉树

 1 from collections import deque
 2 class BinTreeNode(object):
 3     def __init__(self, data, left=None, right=None):
 4         self.data, self.left, self.right = data, left, right
 5 
 6 class BinTree(object):
 7     
 8     def __init__(self, root=None):
 9         self.root = root
10     
11     @classmethod
12     def build_form(cls, node_list):
13         node_dict = {}
14         for node_data in node_list:
15 #这一步是把所有节点存在node_dict中
16             data = node_data['data']
17             node_dict[data] = BinTreeNode(data)
18 '''这一步是根据存在node_dict中的节点字典,把对应的左右节点对应上'''
19         for node_data in node_list:
20             data = node_data['data']
21             if node_data['is_root']:
22                 root = node_dict[data]
23             node_dict[data].left = node_dict.get(node_data['left'])
24             node_dict[data].right = node_dict.get(node_data['right'])
25         return cls(root)

接下来是几种遍历

先序遍历:即先遍历根节点然后遍历左节点接着是右节点

第一种:采用递归

['A', 'B', 'D', 'E', 'H', 'C', 'F', 'G', 'I', 'J']
def prevorder_trav(self, subtree):
        if subtree:
            yield subtree
            yield from self.prevorder_trav(subtree.left)
            yield from self.prevorder_trav(subtree.right)

我个人比较倾向于返回对应节点而不是直接返回值,这样我们还可以对二叉树的每个节点操作。当然你也可以直接返回subtree.date

第二种:采用栈

栈FILO因此我们要先把右节点入栈再把左节点入栈

 1 def prevorder_trav_stack(self, subtree):
 2         s = deque()
 3         s.append(subtree)
 4         while s:
 5             node = s.pop()
 6             yield node
 7             if node.right:
 8                 s.append(node.right)
 9             if node.left:
10                 s.append(node.left)

中序遍历:先遍历左节点再遍历根节点最后遍历右节点,这个先遍历左节点是要遍历最左,左到它下一个左节点为None

第一种:使用递归

['D', 'B', 'H', 'E', 'A', 'F', 'C', 'I', 'G', 'J']
def inorder_trav(self, subtree):
        if subtree:
            yield from self.inorder_trav(subtree.left)
            yield subtree
            yield from self.inorder_trav(subtree.right)

第二种使用栈:

def inorder_trav_use_stack(self, subtree):
        s = deque()
        top = subtree
        while s or top:
            while top:
                s.append(top)
                top = top.left
                
            top = s.pop()
            print(top.data)
            top = top.right

后序遍历

递归

def postorder_trav(self, subtree):
        if subtree:
            yield from self.postorder_trav(subtree.left)
            yield from self.postorder_trav(subtree.right)
            yield subtree.data

使用栈:

def postorder_trav_use_stack(self, subtree):
        p = subtree
        s = deque()
        s.append(p)
        s.append(p)
        while s:
            p = s.pop()
            if s and p == s[-1]:
                if p.right:
                    s.append(p.right)
                    s.append(p.right)
                if p.left:
                    s.append(p.left)
                    s.append(p.left)
            else:
                yield p.data

 层序遍历:

def layer_trav(self, subtree):
        if subtree:
            s = deque()
            s.append(subtree)
            while s:
                node = s.popleft()
                yield node.data
                if node.left:
                    s.append(node.left)
                if node.right:
                    s.append(node.right)

猜你喜欢

转载自www.cnblogs.com/python-zkp/p/10539240.html
今日推荐