【数据结构】二叉树

目录

1、先中后遍历(递归)

2、先序遍历(非递归)

3、中序遍历(非递归)(百度实习)

4、后序遍历(非递归)

5、层次遍历(BFS)


二叉树7种遍历方式

前中后遍历递归+非递归 dfs

层次遍历 bfs

1、先中后遍历(递归)

leetcode 94 二叉树的中序遍历 递归

class Solution(object):
    # 递归
    def inorderTraversal_recursive(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        res = []
        self.helper(root,res)
        return res

    def helper(self,root,res):
        if root:
            self.helper(root.left,res)
            res.append(root.val)
            self.helper(root.right,res)

2、先序遍历(非递归)

二叉树的深度优先遍历就是先序遍历。深度优先是用栈,先进后出广度优先是用堆,先进先出。

二叉树先序遍历(非递归)代码

# 先序打印二叉树(非递归)
def preOrderTravese(node):
    stack = [node]
    while len(stack) > 0:
        print(node.val)
        if node.right is not None:
            stack.append(node.right)
        if node.left is not None:
            stack.append(node.left)
        node = stack.pop()

# 深度优先遍历(非递归)
# 利用栈,先将右子树压栈,再将左子树压栈
"""
深度优先搜索二叉树是先访问根结点,然后遍历左子树接着是遍历右子树,因此我们可以利用栈的先进后出的特点,

先将右子树压栈,再将左子树压栈,这样左子树就位于栈顶,可以保证结点的左子树先与右子树被遍历。
"""
def dfs(self,root):
    stack = []
    rs = []
    if root:
        stack.append(root)
        while stack:
            cur = stack.pop()
            # print(cur.val)
            rs.append(cur.val)
            if cur.right:
                stack.append(cur.right)
            if cur.left:
                stack.append(cur.left)
    print(rs)

3、中序遍历(非递归)(百度实习)

遍历过程如下:

开始根节点入栈

循环执行如下操作:如果栈顶结点左孩子存在,则左孩子入栈;如果栈顶结点左孩子不存在,则出栈并输出栈顶结点,然后检查其右孩子是否存在,如果存在,则右孩子入栈。

当栈空时算法结束。

# 迭代
def inorderTraversal(self, root):
    stack,res = [],[]
    cur = root
    while stack or cur:# 根节点的右子树还未遍历完,此时cur非空
        while cur:
        # travel to each node's left child, till reach the left leaf
            stack.append(cur)
            cur = cur.left
        if stack: # 可以省略
            # this node has no left child
            cur = stack.pop()
            # so let's append the node value 
            res.append(cur.val)
            cur = cur.right
    return res

4、后序遍历(非递归)

# 后序打印二叉树(非递归)
# 使用两个栈结构
# 第一个栈进栈顺序:左节点->右节点->根节点
# 第一个栈弹出顺序: 根节点->右节点->左节点(先序遍历栈弹出顺序:根->左->右)
# 第二个栈存储为第一个栈的每个弹出依次进栈
# 最后第二个栈依次出栈
def postOrderTraverse(node):
    stack = [node]
    stack2 = []
    while len(stack) > 0:
        node = stack.pop()
        stack2.append(node)
        if node.left is not None:
            stack.append(node.left)
        if node.right is not None:
            stack.append(node.right)
    while len(stack2) > 0:
        print(stack2.pop().val)

二叉树先序、中序、后序遍历 递归与非递归 Python实现

5、层次遍历(BFS)

建立一个队列,先将二叉树头结点入队,然后出队,访问该结点;

如果该结点有左子树,则将左子树根结点入队;

如果该结点有右子树,则将右子树根结点入队;

然后出队列(先进先出),对出队结点访问;

如此反复,直到队空为止。

python代码: 

class Solution:
    def levelOrder(self, root):
        if not root: return []
        queue, res = deque([root]), []

        while queue:
            cur_level, size = [], len(queue)
            for i in range(size):
                node = queue.popleft()
                if node.left:
                    queue.append(node.left)
                if node.right:
                    queue.append(node.right)
                cur_level.append(node.val)
            res.append(cur_level)
        return res

Leetcode103. zigzag遍历(也是一种层次遍历啦)

给定二叉树 [3,9,20,null,null,15,7],

    3
   / \
  9  20
    /  \
   15   7

返回锯齿形层次遍历如下:

[
  [3],
  [20,9],
  [15,7]
]
class Solution(object):
    def zigzagLevelOrder(self, root):
        """
        :type root: TreeNode
        :rtype: List[List[int]]
        """
        queue = []
        res = []
        if root:
            queue.append(root)
            flag = 1
            while queue:
                cur_level, size = [], len(queue)
                for i in range(size):
                    cur = queue.pop(0)
                    cur_level.append(cur.val)
                    if cur.left:
                        queue.append(cur.left)
                    if cur.right:
                        queue.append(cur.right)
                res.append(cur_level[::flag])
                flag*=-1
        return res

参考:

from collections import deque

python -- python collections模块中的deque

deque就是双端队列,是一种具有队列和栈的性质的数据结构,适合于在两端添加和删除,类似与序列的容器。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值