鱼C论坛

 找回密码
 立即注册

python 二叉树遍历的非递归算法

热度 1已有 837 次阅读2013-11-2 19:21

以下代码实现了一个二叉树类,包含了它的4种遍历方法,分别是前序遍历,中序遍历,后序遍历和层序遍历。主要是前3种遍历的非递归写法。我们知道,用递归写这三种遍历是很简单也很容易理解的,但是非递归算法却有点难度,研究非递归的算法会加深我们对这一问题的理解。那么该怎么写非递归的程序呢,对于这个问题,我们看到无论哪种遍历,先访问到的节点总是后输出,因为这个特点,所以可以采用栈来模拟;如果是先访问的先输出,则采用队列来模拟。具体到每种遍历算法,代码本身写得写比较容易看懂,因为是python,所以就像写英文文章一样。其中后序遍历估计比较难看懂,本身也不好写,应该可以优化很多,但我暂时搞不定了。

2013年11月13日 18:13:15 Post order has been improved.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

class BinaryTreeNode:

    def __init__(self, data, left, right):
        self.data = data
        self.left = left
        self.right = right

class BinaryTree:

    def __init__(self):
        self.root = None

    def maketree(self, data, left, right):
        self.root = BinaryTreeNode(data, left, right)

    def create(self):
        #data = input()
        data = testdata.pop()
        if data == 0:
            return None
        else:
            self.maketree(data, BinaryTree(), BinaryTree())
            if not self.root.left.create():
                self.root.left = None
            if not self.root.right.create():
                self.root.right = None
            return True

    def is_empty(self):
        if self.root is None:
            return True
        else:
            return False

    def pre_order(self, r):
        if r.root is not None:
            print r.root.data
            if r.root.left is not None:
                self.pre_order(r.root.left)
            if r.root.right is not None:
                self.pre_order(r.root.right)
                
    def pre_order_nonrecursion(self):
        stack = []
        # initialize stack
        stack.append(self.root)
        while len(stack) != 0:
            p = stack.pop()
            print p.data
            if p.right is not None:
                stack.append(p.right.root)
            if p.left is not None:
                stack.append(p.left.root)

    def in_order(self, r):
        if r.root is not None:
            if r.root.left is not None:
                self.in_order(r.root.left)
            print r.root.data
            if r.root.right is not None:
                self.in_order(r.root.right)

    def in_order_nonrecursion(self):
        stack = []
        # initialize stack
        stack.append(self.root)
        p = self.root
        while p.left is not None:
            stack.append(p.left.root)
            p = p.left.root

        while len(stack) != 0:
            p = stack.pop()
            print p.data
            if p.right is not None:
                stack.append(p.right.root)
                p = p.right.root
                while p.left is not None:
                    stack.append(p.left.root)
                    p = p.left.root

    def post_order(self, r):
        if r.root is not None:
            if r.root.left is not None:
                self.post_order(r.root.left)
            if r.root.right is not None:
                self.post_order(r.root.right)
            print r.root.data

    def post_order_nonrecursion(self):
        stack = []
        # initialize stack
        stack.append(self.root)
        p = self.root
        while p.left is not None or p.right is not None:
            if p.right is not None and p.left is not None:
                stack.append(p.right.root)
                stack.append(p.left.root)
                p = p.left.root
            if p.right is not None and p.left is None:
                stack.append(p.right.root)
                p = p.right.root
            if p.right is None and p.left is not None:
                stack.append(p.left.root)
                p = p.left.root

        poplist = []

        while len(stack) != 0:
            tobepoped = stack[-1]
            flag = True
            if tobepoped.left is None and tobepoped.right is None:
                p = stack.pop()
                poplist.append(p)
                print p.data
            elif tobepoped.left is not None and tobepoped.left.root in poplist:
                p = stack.pop()
                poplist.append(p)
                print p.data
                flag = False
            elif flag and tobepoped.right is not None and tobepoped.right.root in poplist:
                p = stack.pop()
                poplist.append(p)
                print p.data
            else:
                p = stack[-1]
                while p.left is not None or p.right is not None:
                    if p.right is not None and p.left is not None:
                        stack.append(p.right.root)
                        stack.append(p.left.root)
                        p = p.left.root
                    if p.right is not None and p.left is None:
                        stack.append(p.right.root)
                        p = p.right.root
                    if p.right is None and p.left is not None:
                        stack.append(p.left.root)
                        p = p.left.root

    def post_order_nonrecursion_v1(self):
        stack_1 = []
        stack_2 = []
        stack_1.append(self.root)

        while len(stack_1) != 0:
            p = stack_1.pop()
            stack_2.append(p.data)
            if p.left is not None:
                stack_1.append(p.left.root)
            if p.right is not None:
                stack_1.append(p.right.root)
        stack_2.reverse()
        print stack_2

    def level_order(self):
        q = []
        p = self.root
        print p.data
        while p is not None:
            if p.left is not None:
                q.append(p.left.root)
            if p.right is not None:
                q.append(p.right.root)
            if len(q) == 0:
                p = None
            else:
                p = q.pop(0)
                print p.data



路过

鸡蛋

鲜花
1

握手

雷人

刚表态过的朋友 (1 人)

评论 (0 个评论)

facelist

您需要登录后才可以评论 登录 | 立即注册

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-20 18:23

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

返回顶部