【数据结构】二叉树(python实现)

1.二叉树的封装

class Node(object):
    """二叉树的节点封装"""
    def __init__(self,elem):
        self.elem = elem
        self.lchild = None
        self.rchild = None

    def __str__(self):
        return self.elem

class Tree(object):
    """二叉树封装"""
    def __init__(self,root=None):
        self.root = root

    def add(self,elem):
        """往二叉树里添加元素"""
        node = Node(elem)

        if not self.root:
            #如果树是空的,则对根节点赋值
            self.root = node
        else:
            queue = []
            #先找树的根节点,存储到变量queue中
            queue.append(self.root)
            #对已有节点进行层次遍历
            while queue:
                #弹出队列的第一个元素
                item = queue.pop(0)
                if not item.lchild:
                    item.lchild = node
                    return
                elif not item.rchild:
                    item.rchild = node
                    return
                else:
                    #如果左右子树都不为空,加入队列继续判断
                    queue.append(item.lchild)
                    queue.append(item.rchild)

2.二叉树的遍历

遍历分为深度优先广度优先
其中,深度优先的遍历模式有3种:先序遍历(根左右)、中序遍历(左根右)、后序遍历(左右根)。
实现方式有2种:堆栈、递归
广度优先的遍历模式是层次遍历,实现方式是队列

   def breadth_travel(self):
        """利用队列实现树的层次遍历"""
        if not self.root:
            return
        queue = []
        queue.append(self.root)
        while queue:
            node = queue.pop(0)
            print(node.elem,end=' ')
            if node.lchild:
                queue.append(node.lchild)
            if node.rchild:
                queue.append(node.rchild)
        print()
        return

深度优先遍历的先、中、后序遍历(递归实现)

   def preorder(self,root):
        if not root:
            return
        print(root.elem,end=' ')
        self.preorder(root.lchild)
        self.preorder(root.rchild)

    def inorder(self,root):
        if not root:
            return
        self.inorder(root.lchild)
        print(root.elem, end=' ')
        self.inorder(root.rchild)

    def postorder(self,root):
        if not root:
            return
        self.postorder(root.lchild)
        self.postorder(root.rchild)
        print(root.elem,end=' ')

3.二叉树的计数

统计二叉树叶子节点的个数、非叶子节点的个数、二叉树的深度。

3.1 统计二叉树叶子节点的个数

思路是:
1.二叉树为空时,叶子节点个数为0
2.当二叉树只有一个根节点时,则根节点就是叶子节点,个数为1
3.其他情况,计算左子树和右子树中叶子节点的和。

    def leafNum(self,root):
        if not root:
            return 0
        if not root.lchild and not root.rchild:
            return 1
        return self.leafNum(root.lchild)+self.leafNum(root.rchild)

3.2 统计二叉树非叶子节点的个数

思路是:
1.二叉树为空时,非叶子节点个数为0
2.当二叉树只有一个根节点时,则根节点就是叶子节点,非叶子节点个数为0
3.其他情况,计算左子树和右子树中非叶子节点的个数再加1(根节点)。

 def NoleafNum(self,root):
        if not root:
            return 0
        if not root.lchild and not root.rchild:
            return 0
        return self.NoleafNum(root.lchild)+self.NoleafNum(root.rchild)+1

3.3 统计二叉树的深度

思路是:
1.二叉树为空时,深度为0
2.当二叉树只有一个根节点时,深度为1
3.其他情况,计算左子树和右子树的最大值再加1(根节点)

    def TreeDepth(self,root):
        if not root:
            return 0
        if not root.lchild and not root.rchild:
            return 1
        lcount = self.TreeDepth(root.lchild)+1
        rcount = self.TreeDepth(root.rchild)+1
        return rcount if lcount<rcount else lcount

4.树的镜像

左右子树镜像反转

    def Mirror(self,root):
        if not root:
            return
        self.Mirror(root.lchild)
        self.Mirror(root.rchild)
        root.lchild,root.rchild = root.rchild,root.lchild

测试代码:



if __name__ == '__main__':
    tree = Tree()
    for i in range(10):
        tree.add(i)
    print('创建树成功')

    print('层次遍历'.center(30,'*'))
    tree.breadth_travel()

    print('先序遍历'.center(30,'*'))
    root = tree.root
    tree.preorder(root)

    print('中序遍历'.center(30, '*'))
    root = tree.root
    tree.inorder(root)

    print('后序遍历'.center(30, '*'))
    root = tree.root
    tree.postorder(root)

    leaf_num = tree.leafNum(root)
    print('叶子节点的个数:%s' %(leaf_num))

    no_leaf_num = tree.NoleafNum(root)
    print('非叶子节点的个数:%s' %(no_leaf_num))

    treeDepth = tree.TreeDepth(root)
    print('该树的深度:%s' %(treeDepth))
    
    print('树的镜像反转'.center(30,'*'))
    tree.Mirror(root)
    tree.breadth_travel()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值