「数据结构」二叉树的遍历以及Python实现

Sina Weibo:小锋子Shawn
Tencent E-mail:403568338@qq.com
http://blog.csdn.net/dgyuanshaofeng/article/details/78015084

1、遍历的种类和理解[1]
    先序遍历(preorder traversal):先处理当前的节点,再处理左、右子树。用法例子:利用节点深度标志每一个节点。实现:递归。

    中序遍历(inorder ~):首先遍历左子树,然后是当前的节点,最后遍历右子树。用法例子:打印已经排好序的一排树。这个好理解,左子树的节点的值总是小于当前的节点的值,而当前的节点的值总是小于右子树任一节点的值。运行时间:O(N)。因为有N个节点,然后要判断节点是否为空节点。实现:递归。

    后序遍历(postorder ~):先处理左、右子树,再处理当前的节点。用法例子:计算一个节点的高度。运行时间:O(N)。实现:递归。

    层次遍历(level-order ~):所有深度为D的节点要在深度D+1的节点之前进行处理,也就是逐层处理,每层处理节点的时候从左到右。实现:利用队列。

2、Python实现[2][3]
    主要参考了资料[2]的代码,然后我使用的是Python3,发现输出有一些奇怪,改了一些代码,接着发现递归过程会使用多重嵌套,然后找到了一个解嵌套,将树展开的一行。代码如下:
# -*- coding: utf-8 -*-
"""
Created on Mon Sep 18 01:49:41 2017

@author: Shawn Yuen
"""

# a helper function
def flatten(ll):
  if isinstance(ll, list):
    for i in ll:
      for element in flatten(i):
        yield element
  else:
    yield ll
    
# Node Class: left and right, also middel
class Node(object):
    def __init__(self, elem=-1, lchild=None, rchild=None):
        self.elem = elem
        self.lchild = lchild
        self.rchild = rchild

# Binary Tree Class
class Tree(object):
    def __init__(self):
        self.root = Node()
        self.myQueue = []

    # Add a Node for a Tree
    def add(self, elem):
        node = Node(elem)
        if self.root.elem == -1:
            self.root = node
            self.myQueue.append(self.root)
        else:
            treeNode = self.myQueue[0]
            if treeNode.lchild == None:
                treeNode.lchild = node
                self.myQueue.append(treeNode.lchild)
            else:
                treeNode.rchild = node
                self.myQueue.append(treeNode.rchild)
                self.myQueue.pop(0)

    def preorder_recursion(self, root):
        ArrayList = list()
        #preoder traversal using recursion
        if root == None:
            return
        #print(root.elem)
        ArrayList.append(root.elem)
        if root.lchild != None:
            ArrayList.append(self.preorder_recursion(root.lchild))
        if root.rchild != None:
            ArrayList.append(self.preorder_recursion(root.rchild))
        return ArrayList

    def inorder_recursion(self, root):
        ArrayList = list()
        #inorder traversal
        if root == None:
            return
        if root.lchild != None:
            ArrayList.append(self.inorder_recursion(root.lchild))
        #print(root.elem)
        if root.elem != None:
            ArrayList.append(root.elem)
        if root.rchild != None:
            ArrayList.append(self.inorder_recursion(root.rchild))
        return ArrayList

    def postorder_recursion(self, root):
        ArrayList = list()
        #postorder traversal
        if root == None:
            return
        if root.lchild != None:
            ArrayList.append(self.postorder_recursion(root.lchild))
        if root.rchild != None:
            ArrayList.append(self.postorder_recursion(root.rchild))
        if root.elem != None:
        #print(root.elem)
            ArrayList.append(root.elem)
        return ArrayList

    def preorder_stack(self, root):
        ArrayList = list()
        if root == None:
            return
        myStack = []
        node = root
        while node or myStack:
            while node:
                #print(node.elem)
                ArrayList.append(node.elem)
                myStack.append(node)
                node = node.lchild
            node = myStack.pop()
            node = node.rchild
        return ArrayList

    def inorder_stack(self, root):
        ArrayList = list()
        if root == None:
            return
        myStack = []
        node = root
        while node or myStack:
            while node:
                myStack.append(node)
                node = node.lchild
            node = myStack.pop()
            #print(node.elem)
            ArrayList.append(node.elem)
            node = node.rchild
        return ArrayList

    def postorder_stack(self, root):
        ArrayList = list()
        if root == None:
            return
        myStack1 = []
        myStack2 = []
        node = root
        myStack1.append(node)
        while myStack1:
            node = myStack1.pop()
            if node.lchild:
                myStack1.append(node.lchild)
            if node.rchild:
                myStack1.append(node.rchild)
            myStack2.append(node)
        while myStack2:
            #print(myStack2.pop().elem)
            ArrayList.append(myStack2.pop().elem)
        return ArrayList 

    def levelorder_queue(self, root):
        ArrayList = list()
        if root == None:
            return
        myQueue = []
        node = root
        myQueue.append(node)
        while myQueue:
            node = myQueue.pop(0)
            #print(node.elem)
            ArrayList.append(node.elem)
            if node.lchild != None:
                myQueue.append(node.lchild)
            if node.rchild != None:
                myQueue.append(node.rchild)
        return ArrayList

if __name__ == "__main__":
    # please modify this parameter
    ###
    N = 15 # the number of Node in a Tree
    ###
    elems = range(N)
    tree = Tree() # new/create a Tree
    for elem in elems:                  
        tree.add(elem) # add Node into Tree

    print("Level-order Traversal using Queue:")
    print(tree.levelorder_queue(tree.root))
    
    print("\nPreorder Traversal using Recursion:")
    flattenlist = flatten(tree.preorder_recursion(tree.root))
    print(list(flattenlist))
    
    print("\nInorder Traversal using Recursion:")
    flattenlist = flatten(tree.inorder_recursion(tree.root))
    print(list(flattenlist))
    
    print("\nPostorder Traversal using Recursion:")
    flattenlist = flatten(tree.postorder_recursion(tree.root))
    print(list(flattenlist))
    
    print("\nPreorder Traversal using Stack:")
    print(tree.preorder_stack(tree.root))
    
    print("\nInorder Traversal using Stack:")
    print(tree.inorder_stack(tree.root))
    
    print("\nPostorder Traversal using Stack:")
    print(tree.postorder_stack(tree.root))
    输出结果如下(大家可以改动主函数里面的N):
Level-order Traversal using Queue:
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

Preorder Traversal using Recursion:
[0, 1, 3, 7, 8, 4, 9, 10, 2, 5, 11, 12, 6, 13, 14]

Inorder Traversal using Recursion:
[7, 3, 8, 1, 9, 4, 10, 0, 11, 5, 12, 2, 13, 6, 14]

Postorder Traversal using Recursion:
[7, 8, 3, 9, 10, 4, 1, 11, 12, 5, 13, 14, 6, 2, 0]

Preorder Traversal using Stack:
[0, 1, 3, 7, 8, 4, 9, 10, 2, 5, 11, 12, 6, 13, 14]

Inorder Traversal using Stack:
[7, 3, 8, 1, 9, 4, 10, 0, 11, 5, 12, 2, 13, 6, 14]

Postorder Traversal using Stack:
[7, 8, 3, 9, 10, 4, 1, 11, 12, 5, 13, 14, 6, 2, 0]


参考资料:
[1]  数据结构与算法分析:C语言描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值