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

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

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)

 

转载于:https://www.cnblogs.com/python-zkp/p/10539240.html

当然,二叉树遍历有三种主要方式:先序遍历(根-左-右)、中序遍历(左-根-右)和后序遍历(左-右-根)。非递归的层次遍历(也叫广度优先遍历,从上到下、从左到右)通常使用队列来辅助实现。 这里分别给出这些遍历的非递归算法代码: 1. 层序遍历(广度优先遍历): ```c #include <stdio.h> #include <stdlib.h> #include <queue> struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; }; void levelOrder(struct TreeNode* root) { if (root == NULL) return; // 使用队列存储每一层的节点 queue<struct TreeNode*> q; q.push(root); while (!q.empty()) { int size = q.size(); for (int i = 0; i < size; i++) { struct TreeNode* node = q.front(); q.pop(); printf("%d ", node->val); // 打印当前节点值 if (node->left != NULL) q.push(node->left); if (node->right != NULL) q.push(node->right); } printf("\n"); // 换行表示新的一层 } } ``` 2. 先序遍历递归和非递归两种方式,这里是非递归版本,使用): ```c void preorderNonRecursive(struct TreeNode* root) { if (root == NULL) return; stack<struct TreeNode*> s; s.push(root); while (!s.empty()) { struct TreeNode* node = s.top(); s.pop(); printf("%d ", node->val); // 打印当前节点值 if (node->right != NULL) s.push(node->right); if (node->left != NULL) s.push(node->left); } } ``` 3. 中序遍历(非递归,同样使用): ```c void inorderNonRecursive(struct TreeNode* root) { if (root == NULL) return; stack<struct TreeNode*> s; struct TreeNode* curr = root; while (curr != NULL || !s.empty()) { while (curr != NULL) { s.push(curr); curr = curr->left; } curr = s.top(); s.pop(); printf("%d ", curr->val); // 打印当前节点值 curr = curr->right; } } ``` 4. 后序遍历(非递归使用两个): ```c void postorderNonRecursive(struct TreeNode* root) { if (root == NULL) return; stack<struct TreeNode*> s1, s2; s1.push(root); while (!s1.empty()) { struct TreeNode* node = s1.top(); s1.pop(); s2.push(node); if (node->left != NULL) s1.push(node->left); if (node->right != NULL) s1.push(node->right); } while (!s2.empty()) { struct TreeNode* node = s2.top(); s2.pop(); printf("%d ", node->val); // 打印当前节点值 } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值