zoukankan      html  css  js  c++  java
  • 二叉树的建立以及遍历的多种实现(python版)

    二叉树是很重要的数据结构,在面试还是日常开发中都是很重要的角色。

    首先是建立树的过程,对比C或是C++的实现来讲,其涉及到了较为复杂的指针操作,但是在面向对象的语言中,就不需要考虑指针, 内存等。首先我们需要定义一个树节点, 我们采用基于链表设计的节点, 首先定义一个数据域, 其次就是左孩子和右孩子。如下定义:

    # 树节点的定义
    class Node:
        def __init__(self, data=-1, lchild=None, rchild=None):
            self.lchild = lchild  # 表示左子树
            self.rchild = rchild  # 表示右子树
            self.data = data  # 表示数据域

    建立树的实现有两种,遍历建树与层次建树,这两种分别是基于堆栈和队列来实现的,先来看看最基本的递归建树。
    递归建树的过程无非就是一路走到底,但是需要将节点的左右孩子节点对其余的节点相关联起来。因此,我们可以如此来实现:

    def traversal_create(self, root):
    data = input()
    if data is "#":
    return None
    else:
    root.data = data
    root.lchild = self.traversal_create(root.lchild)
    root.rchild = self.traversal_create(root.rchild)
    return root

    首先我们传入的参数是一个默认的节点,其data数据域为-1,然后我们接受输入的数据,赋值给节点数据域,然后就是递归了,将左右孩子节点关联起来。总体来讲,应该不难理解。

    下面看看层次建树的实现,所谓层次建树其实就是基于队列的操作,利用队列先进先出的特点,每次我们访问一个节点的时候,将其存入队列中,待遍历玩当前节点的左右孩子节点,队列就弹出一个节点,之后的操作都是一样的。看看代码:

    def add(self, elem):
    node = Node(elem)
    # 根节点
    if self.root.data == -1:
    self.root = node
    self.myQueue.append(self.root)
    else:
    treeNode = self.myQueue[0] # 记录结点
    if treeNode.lchild is None:
    treeNode.lchild = node
    self.myQueue.append(treeNode.lchild)
    else:
    treeNode.rchild = node
    self.myQueue.append(treeNode.rchild)
    self.myQueue.popleft() # 弹出已经处理好左右子树的父结点

    我们输入一个数据,然后根据数据初始化一个节点,放入队列中,随后就是访问的操作了。

    树的三序遍历就不用说了,基于递归的,很好理解,那么基于队列以及堆栈的的遍历呢?
    对比下基于队列的建树,我们完全可以写出基于队列的遍历, 也是使用队列来存储节点,然后输出左右孩子的数据:

    # 层次遍历 使用队列
    def queue_tarversal(self, root):
    if root is None:
    return
    q = deque()
    q.append(root)
    while q:
    node = q.pop()
    print(node.data)
    if node.lchild is not None:
    q.append(node.lchild)
    else:
    q.append(node.rchild)

    基于堆栈的呢?联想下堆栈的特点,我们一路沿着左子树遍历下去,同时使用堆栈来存储元素,然后在弹出遍历右孩子节点:

    # 使用堆栈来遍历
    def stack_traversal(self, root):
    if root is None:
    return
    mystack = []
    node = root
    while node or mystack:
    while node:
    print(node.data)
    mystack.append(node)
    node = node.lchild
    node = mystack.pop()
    node = node.rchild

    数据结构是难点也是基础,不管怎么样都应该好好学习。

    完整代码:

    ''' 二叉树的建立及实现 (递归与非递归) '''
    from collections import deque
    
    
    # 树节点的定义
    class Node:
        def __init__(self, data=-1, lchild=None, rchild=None):
            self.lchild = lchild  # 表示左子树
            self.rchild = rchild  # 表示右子树
            self.data = data  # 表示数据域
    
    
    class Create_Tree:
        def __init__(self):
            self.root = Node()  # 表示结点
            self.myQueue = deque()  # 使用队列不会有太多的内存开销
    
        # 按层次生成树
        def add(self, elem):
            node = Node(elem)
            # 根节点
            if self.root.data == -1:
                self.root = node
                self.myQueue.append(self.root)
            else:
                treeNode = self.myQueue[0]  # 记录结点
                if treeNode.lchild is None:
                    treeNode.lchild = node
                    self.myQueue.append(treeNode.lchild)
                else:
                    treeNode.rchild = node
                    self.myQueue.append(treeNode.rchild)
                    self.myQueue.popleft()  # 弹出已经处理好左右子树的父结点
    
        # 递归建树
        def traversal_create(self, root):
            data = input()
            if data is "#":
                return None
            else:
                root.data = data
                root.lchild = self.traversal_create(root.lchild)
                root.rchild = self.traversal_create(root.rchild)
            return root
    
        # 前序遍历输出
        def digui(self, root):
            if root is None:
                return
            print(root.data)
            self.digui(root.lchild)
            self.digui(root.rchild)
    
        # 使用堆栈来遍历
        def stack_traversal(self, root):
            if root is None:
                return
            mystack = []
            node = root
            while node or mystack:
                while node:
                    print(node.data)
                    mystack.append(node)
                    node = node.lchild
                node = mystack.pop()
                node = node.rchild
    
        # 层次遍历 使用队列
        def queue_tarversal(self, root):
            if root is None:
                return
            q = deque()
            q.append(root)
            while q:
                node = q.pop()
                print(node.data)
                if node.lchild is not None:
                    q.append(node.lchild)
                else:
                    q.append(node.rchild)
    
    
    if __name__ == "__main__":
        elems = range(10)
        tree = Create_Tree()
        for i in elems:
            # 非递归建树,主要就是根据 队列FIFO的特点以及广度遍历的思路
            tree.add(i) 
    
        # 递归建树
        # tree.traversal_create(tree.root)
    
        # 递归遍历
        tree.digui(tree.root)
        # 栈遍历
        # tree.stack_traversal(tree.root)
    View Code
  • 相关阅读:
    weblogic12c 2021.4.20 季度补丁 SPB
    一顿debug猛如虎,原来内存OOM
    JDK记录一下
    213. 打家劫舍 II-动态规划-中等
    5526. 最多可达成的换楼请求数目-回溯-困难
    1584. 连接所有点的最小费用-图/最小生成树-中等
    Java-泛型的限制
    Java-泛型-桥方法
    889. 根据前序和后序遍历构造二叉树-树-中等
    1109. 航班预订统计-差分数组-中等
  • 原文地址:https://www.cnblogs.com/zhiyong-ITNote/p/7844636.html
Copyright © 2011-2022 走看看