zoukankan      html  css  js  c++  java
  • 遍历算法总结

    1 概念

    先序遍历:节点 - 左孩子 - 右孩子
    中序遍历:左孩子 - 根结点 - 右孩子
    后序遍历:左孩子 - 右孩子 - 根结点

    前序遍历:- + a * b – c d / e f
    中序遍历:a + b * c – d – e / f
    后序遍历:a b c d – * + e f / -

    2 python的前中后序递归算法实现

    class BinTree():
            def __init__(self, value, left=None, right=None):
                    self.value = value
                    self.left = left
                    self.right = right
    
    def initial_tree():
            a = BinTree(1)
            b = BinTree(2)
            c = BinTree(7, a, b)
            d = BinTree(4)
            e = BinTree(3, c, d)
            return e
    
    def pre_traversal(bin_tree):
            if bin_tree is None:
                    return
            print bin_tree.value
            if bin_tree.left is not None:
                    pre_traversal(bin_tree.left)
            #print bin_tree.value 
            if bin_tree.right is not None:
                    pre_traversal(bin_tree.right)
            #print bin_tree.value
    test = initial_tree()
    pre_traversal(test)

    如果把print bin_tree.value放到前边就是前序遍历;放到中间就是中序遍历;放到后边就是后序遍历。

    3 python的前中后序非递归算法实现

    前序遍历实现:

    def pre_traversal_no_cur(bin_tree):
        if bin_tree is None:
            return
        tree_stack = []
        tree_stack.append(bin_tree)
        while len(tree_stack) > 0:
            tmp = tree_stack.pop()
            print tmp.value
            if tmp.right is not None:
                tree_stack.append(tmp.right)
            if tmp.left is not None:
                tree_stack.append(tmp.left)

    中序遍历实现:

    def mid_traversal_no_cur(bin_tree):
        if bin_tree is None:
                    return
        tree_stack = []
        tmp = bin_tree
        while tmp is not None or len(tree_stack) > 0:
            while tmp is not None:
                tree_stack.append(tmp)
                tmp = tmp.left
            if len(tree_stack) > 0:
                tmp = tree_stack.pop()
                print tmp.value
                tmp = tmp.right

    后序遍历非递归的实现的关键点,在于判断出这个节点的右节点有没有已经被遍历过一遍了,所以实现1和实现2其实都是用来记住是否被遍历过一遍了。
    实现2抓住的一点是,假设节点x,则x的右子节点遍历输出后,接着的一定是开始输出x自己,所以可以用个q来保存上个输出的节点,然后用x.right判断上个输出的是不是右节点
    后序遍历实现1:

    def after_traversal_two_stack(bin_tree):
        if bin_tree is None:
                    return
        s1 = []
        s2 = []
        tmp = bin_tree
        while tmp is not None or len(s1) > 0:
            while tmp is not None:
                s1.append(tmp)
                s2.append(0)
                tmp = tmp.left
            if len(s1) > 0:
                tmp = s1[-1]
                if s2[-1] == 1 or tmp.right is None:
                    tmp = s1.pop()
                    s2.pop()
                    print tmp.value
                    tmp = None
                else:
                    s2[-1] = 1
                    tmp = tmp.right

    后序遍历实现2:

    def after_traversal_single_stack(bin_tree):
        if bin_tree is None:
            return
        s1 = []
        q = None
        tmp = bin_tree
        while tmp is not None or len(s1) > 0:
            while tmp.left is not None:
                s1.append(tmp)
                tmp = tmp.left
            while tmp.right is None or tmp.right == q:
                print tmp.value
                q = tmp
                if len(s1) <= 0:
                    return
                tmp = s1.pop()
            s1.append(tmp)
            tmp = tmp.right

    4 层次遍历

    这里用到了deque模块,这里其实可以相当于是栈和队列,因为pop默认是pop出最后一个,popleft则是pop出第一个。
    也可以直接像数组那样访问,d[0]、d[-1]等

    from collections import deque
    def level_traversal(bin_tree):
            if bin_tree is None:
                    return
            queue = deque([])
            queue.append(bin_tree)
            while len(queue) > 0:
                    tmp = queue.popleft()
                    print tmp.value
                    if tmp.left is not None:
                            queue.append(tmp.left)
                    if tmp.right is not None:
                            queue.append(tmp.right)
  • 相关阅读:
    那些离不开的 Chrome 扩展插件
    Spring Boot 实战 —— 入门
    Maven 学习笔记
    Linux lvm 分区知识笔记
    Linux 双向 SSH 免密登录
    CentOS Yum 源搭建
    Ubuntu 系统学习
    iOS 测试三方 KIF 的那些事
    Swift 网络请求数据与解析
    iOS Plist 文件的 增 删 改
  • 原文地址:https://www.cnblogs.com/luohaixian/p/10616949.html
Copyright © 2011-2022 走看看