数据结构和算法分析(六)--树(1)--树的概念和实现


树广泛应用于计算机科学的多个领域,从操作系统、图形学、数据库到计算机网络。作为数据结构的树和现实世界中的树有很多共同之处,二者皆有根、枝、叶,不同之处在于,前者的根在顶部,而叶在底部。

一、树的定义

定义一:树由节点及连接节点的边构成。树有以下属性

  • 有一个根节点;
  • 除根节点外,其他每个节点都与其唯一的父节点相连;
  • 从根节点到其他每个节点都有且仅有一条路径;
  • 如果每个节点最多有两个节点,我们就称这样的树为二叉树

定义二:一棵树要么为空,要么由一个根节点和零棵或多棵子树构成,子树本身也是一棵树。每棵子树的根节点通过一条边连接到父树的根节点。

二、树的相关概念

  • 节点:节点是树的基础部分,它可以有自己的名字,我们称作“键”。节点也可以带有附加信息,我们称作“有效载荷”;
  • 边:边是树的另一个基础部分,两个节点通过一条边相连,表示他们之间存在关系。除了根节点之外,其他每个节点都仅有一条入边,出边则可能有多条;
  • 根节点:根节点是树中唯一没有入边的节点;
  • 路径:路径是由边连接的有序节点列表;
  • 子节点:一个节点通过出边与子节点相连;
  • 父节点:一个节点是其所有子节点的父节点;
  • 兄弟节点:具有同一父节点的节点互称为兄弟节点;
  • 子树:一个父节点及其所有后代的节点和边构成一棵子树;
  • 叶子节点:叶子节点没有子节点;
  • 层数:节点n的层数是从根节点到n的唯一路径长度;
  • 高度:树的高度是其中节点层数的最大值。

三、树的实现

可以使用以下函数创建并操作二叉树

  • BinaryTree()创建一个二叉树实例;
  • getLeftChild()返回当前节点的左子节点所对应的二叉树;
  • getRightChild()返回当前节点的右子节点所对应的二叉树;
  • setRootVal(val)在当前节点中存储参数val中的对象;
  • getRootVal()返回当前节点存储的对象;
  • insertLeft(val)新建一棵二叉树,并将其作为当前节点的左子节点;
  • insertRight(val)新建一棵二叉树,并将其作为当前节点的右子节点。

(1)列表之列表

用列表构建树时,我们将根节点的值作为列表的第一个元素;第二个元素代表左子树的列表;第三个元素代表右子树列表。
列表之列表表示法有个很好的性质,那就是表示子树的列表结构符合树的定义,这样的结构是递归的。

列表函数BinaryTree

def BinaryTree(r):
    return [r, [], []]

该函数构造一个简单的列表,它仅有一个根节点和两个作为子节点的空列表。要添加左子树,需要在列表的第二个位置加入一个新列表,如果列表的第二个位置上已由内容,我们需要保留已有内容,并将其作为新列表的左子树。

插入左子树函数

def insertLeft(root, newBranch):
    # 获取左子树
    t = root.pop(1)
    if len(t) > 1:
        # 若存在左子树,则将其作为新节点的左子树插入列表
        root.insert(1, [newBranch, t, []])
    else:
        # 若不存在左子树,则添加新节点即可
        root.insert(1, [newBranch, [], []])
    return root

插入右子树

def insertRight(root, newBranch):
    # 获取右子树
    t = root.pop(2)
    if len(t) > 1:
        # 如果存在右子树,则将作为新节点的右子树插入列表
        root.insert(2, [newBranch, [], t])
    else:
        # 如果不存在,则添加新节点即可
        root.insert(2, [newBranch, [], []])
    return root

树的访问函数

# 获取根节点元素
def getRootVal(root):
    return root[0]

# 设置根节点元素
def setRootVal(root, newVal):
    root[0] = newVal

# 获取左子树
def getLeftChild(root):
    return root[1]

# 获取右子树
def getRightChild(root):
    return root[2]

(2)节点与引用

树的第二种表示法是利用节点与引用,我们定义一个类,其中有根节点和左右子树的属性。
“节点与引用”表示法的要点是,属性left和right会指向BinaryTree类的其他实例。

BinaryTree类

class BinaryTreee:
    def __init__(self, rootObj):
        self.key = rootObj
        self.leftChild = None
        self.rightChild = None

插入左子节点

    def insertLeft(self, newNode):       
        if self.leftChild == None:
            # 如果当前节点没有左子树,直接将其左子节点设置为新插入的节点即可
            self.leftChild = BinaryTreee(newNode)
        else:
            # 如果当前节点有左子节点
            # 先创建新节点
            t = BinaryTreee(newNode)
            # 将新节点的左子节点指向之前的左子节点
            t.leftChild = self.leftChild
            # 将当前节点的左子节点指向新节点
            self.leftChild = t

插入右子节点

    def insertRight(self, newNode):
        if self.rightChild == None:
            # 如果当前节点没有右子树,直接将其右子节点设置为新插入的节点即可
            self.rightChild = BinaryTreee(newNode)
        else:
            # 如果当前节点没有右子节点
            # 先创建新节点
            t = BinaryTreee(newNode)
            # 将新节点的右子树指向之前的右子节点
            t.rightChild = self.rightChild
            # 将当前节点的右子节点指向新节点
            self.rightChild = t

二叉树的访问函数

	# 获取右子树
    def getRightChild(self):
        return self.rightChild

    # 获取左子树
    def getLeftChild(self):
        return self.leftChild

    # 设置根节点元素
    def setRootVal(self, obj):
        self.key = obj

    # 获取根节点元素
    def getRootVal(self):
        return self.key

本系列为《Python数据结构与算法分析》第二版学习笔记,作者:布拉德利.米勒;戴维.拉努姆。译:吕能, 刁寿钧

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值