数据结构与算法-树

一、树的基本概念

节点、边、根节点、叶子节点、分支节点、子树

二、基本术语

1.节点之间的关系:父节点、子节点、祖先节点、子孙节点、兄弟节点、堂兄弟节点,节点之间的路径--只能从上往下,路径长度--路径上经过多少条边

2.节点、树的属性:节点的深度、节点的高度、树的深度、节点的度、树的度(节点度的最大值)

3.有序树和无序树:逻辑上看,各子树是否有序,位置是否可以互换

4.森林:由m个互不相交的树组成森林

5.节点的权:有某种现实含义的数值(如:表示节点的重要性等)

6.节点的带权路径长度:从树的根到该节点的路径长度(经过的边数)与该节点上权值的乘积

7.树的带权路径长度:树中所有叶节点的带权路径长度之和

三、二叉树的基本概念

1.二叉树是n个节点的有限集合

2.空二叉树,n=0

3.由一个根节点和两个互不相交的被称为根的左子树和右子树组成,左子树和右子树又分别是一颗二叉树

4.每个节点最多只有两棵子树

5.左右子树不能颠倒

四、几个特殊二叉树

1.满二叉树, 只有最后一层有叶子节点,不存在度为1的节点

2.完全二叉树,每层的节点与满二叉树一一对应,满二叉树是一种完全二叉树

3.二叉排序树,左子树上节点的编号均小于根节点编号,右子树上所有节点关键字均大于根节点,左右子树又各是一棵二叉排序树,常用于搜索

4.平衡二叉树,左子树和右子树的深度之差不超过1

5.哈夫曼树:带权路径最短的二叉树称为哈弗曼树或最优二叉树

6.B树:一种对读写操作进行优化的自平衡的二叉查找树,能够保持数据有序,拥有多余两个子树

五、哈夫曼树的构造

1.权值最小的先组合,新节点的权值为左右子树的权值之和

2.组合的新二叉树的根节点与另外最小权值的节点组合

3.如果有两个节点均小于第一个二叉树的跟节点,就让那两个节点先结合

六、二叉树遍历

1.先序遍历(深度优先遍历)

先根、再左、再右,即ABCDEFGHK

2.中序遍历(深度优先遍历)

先左、再根、再右,即BDCAEHGKF

3.后序遍历(深度优先遍历)

先左、再右、再根,即DCBHKGFEA

4.层次遍历(广度优先遍历)

从上到下,从左到右进行遍历

七、代码实现

# 二叉树的链式存储

# 二叉树的节点类
class TreeNode:
    def __init__(self, val=None, left=None, right=None):
        self.val = val  # 树节点存储的值
        self.left = left  # 左子树
        self.right = right  # 右子树


# 二叉树类
class BinaryTree:
    def __init__(self):
        self.root = None  # 根节点初始化为None
        self.addr_list = []  # 节点地址

    def add(self, data):
        node = TreeNode(data)  # 实例化树节点
        if self.root is None:  # 如果根节点为空,则添加根节点,将地址存入addr中
            self.root = node
            self.addr_list.append(self.root)
        else:
            root_node = self.addr_list[0]  # 将第一个元素设为根节点
            if root_node.left is None:  # 添加左孩子
                root_node.left = node
                self.addr_list.append(root_node.left)
            elif root_node.right is None:  # 添加右孩子
                root_node.right = node
                self.addr_list.append(root_node.right)
                self.addr_list.pop(0)  # 添加完右孩子之后,下一轮要添加的节点,是以根节点下面一个节点为根节点,所以需要删除掉第一个根节点

    # 先序
    def pre_traverse(self, root):
        if root is None:
            return
        print(root.val, end=" ")
        self.pre_traverse(root.left)
        self.pre_traverse(root.right)

    # 中序
    def mid_traverse(self, root):
        if root is None:
            return
        self.mid_traverse(root.left)
        print(root.val, end=" ")
        self.mid_traverse(root.right)

    # 后序
    def back_traverse(self, root):
        if root is None:
            return
        self.mid_traverse(root.left)
        self.mid_traverse(root.right)
        print(root.val, end=" ")

    # 层次遍历
    def level_traverse(self, root):
        from collections import deque
        queue = deque()
        queue.append(root)
        while len(queue) > 0:
            node = queue.popleft()
            print(node.val, end=' ')
            if node.left:
                queue.append(node.left)
            if node.right:
                queue.append(node.right)


if __name__ == '__main__':
    tree = BinaryTree()
    for i in range(1, 11):
        tree.add(i)
    print("先序遍历:", end=" ")
    tree.pre_traverse(tree.root)
    print()
    print("中序遍历:", end=" ")
    tree.mid_traverse(tree.root)
    print()
    print("后序遍历:", end=" ")
    tree.back_traverse(tree.root)
    print()
    print("层次遍历:", end=" ")
    tree.level_traverse(tree.root)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Z_ForWard

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值