【数据结构】树

一、树形结构(层次结构)

1.1 基本概念

树形结构:数据元素之间存在一对多的关系

树:树是由根结点和若干个子结点组成的树形结构

结点:树的基本单位

根结点:没有父结点的节点称为根结点

父结点:当前结点的直接上级节点称为该节点的父结点

孩子结点:当前结点的直接下级节点称为该节点的孩子节点

兄弟节点:拥有相同父结点的结点互为兄弟节点

堂兄弟结点:其父结点在同一层次的结点互为堂兄弟结点

祖先结点:当前结点的直接或间接上级节点

子孙节点:当前结点的直接或间接下级节点

叶子节点:度为0的节点,或者说是没有孩子节点的节点

节点的度:就是该节点的子节点的个数

树的度:当前树中的节点的度的最大值就是树的度

节点的层次:从根结点出发,到该节点处所经历的层次称为该节点的层次

树的层次(深度):节点层次的最大值就是树的层次

森林:由m(m>=0)个不相交的树构成的树形结构叫做森林

1.2 二叉树

每个节点最多拥有两个节点的树,并且严格区分左右子树的树形结构。

1.3 二叉树的相关概念

1】左子树:以当前节点的左孩子为根节点的子树称为该节点的左子树

2】右子树:以当前节点的右孩子为根节点的子树称为该节点的右子树

3】左斜树:该树上的每个节点都只有左孩子节点,没有右孩子节点的树

4】右斜树:该树上的每个节点都只有右孩子节点,没有左孩子节点的树

5】满二叉树:在不增加层次的基础上,不能再向树上增加节点

6】完全二叉树:在满二叉树的基础上,从左往右依次增加节点的二叉树叫完全二叉树

 

1.5 二叉树的性质

1】在一个二叉树的第i层上,最多拥有2^(i-1)个节点

2】前k层最多拥有2^k - 1个节点

3】在任意一个二叉树上,叶子节点的个数总比度为2的节点数目多一个

总节点数 = 总度树+1 n0 表示度为0 的节点 n1表示度为1的节点 n2表示度为2的节点

总节点数:n0+n1+n2

总度数:n1*1 + n2*2

n0+n1+n2 = n1*1 + n2*2 +1 n0 = n2 +1 

1.6 二叉树的顺序存储 

 

对于树的顺序存储而言,如果是满二叉树或者是完全二叉树的话,使用顺序存储没有任何问题,但是,如果是普通二叉树,那就会造成空间浪费,所以,一般对二叉树的存储,通常使用链式存储。 

1.7 二叉树的链式存储 

 

1.7.1 节点和树类的类型封装 

#封装树的节点的类
class Node:
    #显性定义构造函数
    def __init__(self,data,lchild = None, rchild = None):
        self.data = data #树节点的数据域
        self.lchild = lchild #左孩子的位置
        self.rchild = rchild #右孩子的位置


#封装树的类型
class Tree:
    #构造函数
    def __init__(self,root = None):
        self.root = root #树的根
        self.index = 0  #用于遍历一串数据的索引

1.7.2 创建二叉树 

 

#二叉树的创建
def tree_create(self,data_str):
    if self.index >= len(data_str):
        return None

    #获取一个节点的数据
    data = data_str[self.index]
    self.index+=1

    if data == '#':
        return None

    #创建节点
    node = Node(data)
    node.lchild = self.tree_create(data_str)#递归创建左子树
    node.rchild = self.tree_create(data_str)#递归创建右子树
    return node

1.7.3 先序遍历

功能:每次遍历到节点时,先访问数据域,然后访问左子树,最后访问右子树。 ----->根 左 右

#先序遍历
def pri_show(self,node):
    if node is not None:
        #根
        print(node.data, end=' ')
        #左
        self.pri_show(node.lchild)
        #右
        self.pri_show(node.rchild)

1.7.4 中序遍历

功能:每次遍历到节点时,先访问左子树,然后访问数据域,最后访问右子树。 ----->左 根 右

# 中序遍历
def mid_show(self, node):
    if node is not None:
        # 左
        self.mid_show(node.lchild)
        # 根
        print(node.data, end=' ')
        # 右
        self.mid_show(node.rchild)

1.7.5 后序遍历

功能:每次遍历到节点时,先访问数据域,然后访问问右子树,最后访问数据域。 ----->左 右 根

# 后序遍历
def last_show(self, node):
    if node is not None:
        # 左
        self.last_show(node.lchild)

        # 右
        self.last_show(node.rchild)

        # 根
        print(node.data, end=' ')

 代码:

#封装树的节点的类
class Node:
    #显性定义构造函数
    def __init__(self,data,lchild = None, rchild = None):
        self.data = data #树节点的数据域
        self.lchild = lchild #左孩子的位置
        self.rchild = rchild #右孩子的位置


#封装树的类型
class Tree:
    #构造函数
    def __init__(self,root = None):
        self.root = root #树的根
        self.index = 0  #用于遍历一串数据的索引


    #二叉树的创建
    def tree_create(self,data_str):
        if self.index >= len(data_str):
            return None

        #获取一个节点的数据
        data = data_str[self.index]
        self.index+=1

        if data == '#':
            return None

        #创建节点
        node = Node(data)
        node.lchild = self.tree_create(data_str)#递归创建左子树
        node.rchild = self.tree_create(data_str)#递归创建右子树
        return node

    #先序遍历
    def pri_show(self,node):
        if node is not None:
            #根
            print(node.data, end=' ')
            #左
            self.pri_show(node.lchild)
            #右
            self.pri_show(node.rchild)

    # 中序遍历
    def mid_show(self, node):
        if node is not None:
            # 左
            self.mid_show(node.lchild)
            # 根
            print(node.data, end=' ')
            # 右
            self.mid_show(node.rchild)

    # 后序遍历
    def last_show(self, node):
        if node is not None:
            # 左
            self.last_show(node.lchild)
            
            # 右
            self.last_show(node.rchild)

            # 根
            print(node.data, end=' ')



#测试
if __name__ == "__main__":
    #输入一组数据
    data_str = input("输入二叉树的序列:")

    #创建二叉树
    tree = Tree()
    tree.root = tree.tree_create(data_str)

    #遍历
    print("先序遍历结果:")
    tree.pri_show(tree.root)
    print()

    print("中序遍历结果:")
    tree.mid_show(tree.root)
    print()

1.8 根据已知序列反推二叉树

1】由先序序列和中序序列反推二叉树

 

 

已知树画遍历也很简单,记住遍历的顺序如左右根,每一个结点画完左右根之后依次按顺序细分,直到分完了按层次书写 

 2】由后序序列和中序序列反推二叉树

 

 

3】不能通过先序和后序返推二叉树 

 

缺乏结构信息

  • 先序遍历的顺序是:根节点 -> 左子树 -> 右子树。
  • 后序遍历的顺序是:左子树 -> 右子树 -> 根节点。

这两种遍历方式都只提供了节点访问的顺序,而没有提供关于节点之间连接关系的明确信息。特别是,它们都没有明确说明哪些节点是哪些节点的父节点、左子节点或右子节点

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值