07_05.通过链接实现二叉树及其遍历

from queue.queue import SQueue
from sstack.stack import SStack


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


def count_BinTNodes(t):
    """统计树中结点个数"""
    if t is None:
        return 0
    else:
        return 1 + count_BinTNodes(t.left) + count_BinTNodes(t.right)


def sum_BinTNodes(t):
    """所有数值和(二叉树保存的是数值)"""
    if t is None:
        return 0
    else:
        return t.data + sum_BinTNodes(t.left) + sum_BinTNodes(t.right)

遍历:

先根序遍历递归:

def preorder(t, proc):
    """先根序遍历"""
    if t is None:
        return
    assert (isinstance(t, BinTNode))
    proc(t.data)
    preorder(t.left, proc)
    preorder(t.right, proc)


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
preorder(tree, lambda x: print(x, end=' '))  # 1 2 4 5 3 6 7
print()


def print_BinTNodes(t):
    """先根序遍历打印"""
    if t is None:
        print("^", end="")
        return
    print("(" + str(t.data), end="")
    print_BinTNodes(t.left)
    print_BinTNodes(t.right)
    print(")", end="")


t = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
print_BinTNodes(t)  # (1(2(4^^)(5^^))(3(6^^)(7^^)))
print()

先根序遍历非递归:

def preorder_nonrec(t, proc):
    """非递归的先根遍历--用栈"""
    s = SStack()
    while t is not None or not s.is_empty():
        while t is not None:
            proc(t.data)  # 先处理根
            s.push(t.right)  # 右分支入栈
            t = t.left  # 沿左分支下行
        t = s.pop()  # 遇到空树回溯


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
preorder_nonrec(tree, lambda x: print(x, end=' '))  # 1 2 4 5 3 6 7
print("")

先根序遍历非递归优化:

def preorder_elements(t):
    """非递归的先根遍历优化,使用生成器"""
    s = SStack()
    while t is not None or not s.is_empty():
        while t is not None:
            s.push(t.right)  # 右分支入栈
            yield t.data
            t = t.left  # 沿左分支下行
        t = s.pop()  # 遇到空树回溯


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
for i in preorder_elements(tree):
    print(i, end=' ')  # 1 2 4 5 3 6 7

 

宽度优先遍历:

def levelorder(t, proc):
    """宽度优先遍历"""
    qu = SQueue()
    qu.enqueue(t)
    while not qu.is_empty():
        n = qu.dequeue()
        if n is None:  # 弹出的树为空则直接跳过
            continue
        qu.enqueue(n.left)
        qu.enqueue(n.right)
        proc(n.data)


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
levelorder(tree, lambda x: print(x, end=' '))  # 1 2 3 4 5 6 7
print("")

非递归实现后根序遍历:

def postorder_nonrec(t, proc):
    """非递归实现后根序遍历"""
    s = SStack()
    while t is not None or not s.is_empty():
        while t is not None:  # 下行循环,直到栈顶的两子树空
            s.push(t)
            t = t.left if t.left is not None else t.right
        t = s.pop()  # 栈顶是访问结点
        proc(t.data)
        if not s.is_empty() and s.top().left == t:  # 栈不为空且访问结点是栈顶的左子结点
            t = s.top().right
        else:  # 没有右子树或右子树遍历完毕,进行退栈
            t = None


tree = BinTNode(1, BinTNode(2, BinTNode(4), BinTNode(5)), BinTNode(3, BinTNode(6), BinTNode(7)))
postorder_nonrec(tree, lambda x: print(x, end=' '))  # 4 5 2 6 7 3 1
print()

 将二叉树封装成类:

"""二叉树类"""
from sstack.stack import SStack


class BinTNode:
    """结点"""
    def __init__(self, data, left=None, right=None):
        self.data = data
        self.left = left
        self.right = right


class BinTree:
    """二叉树"""
    def __init__(self):
        self._root = None

    def is_empty(self):
        return self._root is None

    def root(self):
        return self._root

    def leftchild(self):
        return self._root.left

    def rightchild(self):
        return self._root.right

    def set_root(self, rootnode):
        self._root = rootnode

    def set_left(self, leftchild):
        self._root.left = leftchild

    def set_right(self, rightchild):
        self._root.right = rightchild

    def preorder_elements(self):
        t, s = self._root, SStack()
        while t is not None or not s.is_empty():
            while t is not None:
                s.push(t.right)
                yield t.data
                t = t.left
            t = s.pop()


l = BinTNode(2, BinTNode(4), BinTNode(5))
r = BinTNode(3, BinTNode(6), BinTNode(7))
tree = BinTree()
tree.set_root(BinTNode(1))
tree.set_left(l)
tree.set_right(r)
for i in tree.preorder_elements():
    print(i, end=' ')  # 1 2 4 5 3 6 7
print()

 

posted @ 2019-11-07 16:10  fly_bk  阅读(204)  评论(0)    收藏  举报