数据结构(Python版):树(Tree)、二叉树(Binary Tree)

本文介绍了树结构的基础知识,特别是二叉树的概念,包括如何创建二叉树节点、插入节点以及获取节点值等操作。此外,详细阐述了二叉树的三种遍历方式:前序、中序和后序遍历。接着,讨论了平衡二叉树、完全二叉树、满二叉树和二叉查找树等常见类型的特性与区别。通过实例展示了如何使用Python实现二叉树结构及其遍历方法。
摘要由CSDN通过智能技术生成

0. 树(Tree)

树(Tree)是有限个数据节点(即数据项)组成的集合,其中除根节点和叶的下标为外,每个节点都具有一个直接先驱节点和多个直接后继节点,这与每节点仅具有一个直接先驱节点和一个直接后继节点的线性结构不同;树结构中,根节点(Root)没有先驱节点,叶节点(Leaf)没有后续节点。

1. 二叉树(Binary Tree)

1.1 二叉树的定义

如果树中的每个节点最多可以有两个后续节点,那么这样的树状结构称为二叉树,这是树状结构中最为常用的一种。二叉树(Binary Tree)定义的操作如下:

  1. BinaryTree:创建一个二叉树节点;
  2. insertLeft:将新节点插入树中作为其直接的左子节点;
  3. insertRight:将新节点插入树中作为其直接的右子节点;
  4. getRootVal:返回本节点的值;
  5. setRootVal:设置本节点的值;
  6. getLeftChild:返回左子树;
  7. getRightChild:返回右子树。

代码实现:
Python语言中,树结构可基于链表或嵌套列表实现。

嵌套列表法的优点是:子树的结构与树相同,是一种递归数据结构;且很容易扩展到多叉树,仅需要增加列表元素即可。但时间复杂度较高,嵌套列表法中,子树节点插入操作借助python列表(list)数据类型的 pop(n) 方法和 insert(n) 方法实现,其时间复杂度是 O(n)。其它二叉树定义方法基于列表(list)索引实现,时间复杂度是 O(1)。

同样可以用节点链接法(链表)来实现树,每个节点保存根节点的数据项,以及指向左右子树的链接,其所有操作的时间复杂度都是 O(1)。

class BinaryTree(object):
    """
    BinaryTree:创建一个二叉树节点;
	insertLeft:将新节点插入树中作为其直接的左子节点;
	insertRight:将新节点插入树中作为其直接的右子节点;
	getRootVal:返回本节点的值;
	setRootVal:设置本节点的值;
	getLeftChild:返回左子树;
	getRightChild:返回右子树。
    """
    def __init__(self, key, val, left=None, right=None
                 , parent=None):
        self.key = key
        self.payload = val
        self.leftChild = left
        self.rightChild = right
        self.parent = parent

    def insertLeftChild(self, key, val, **kwargs):
        if self.leftChild is None:
            temp = BinaryTree(key, val, **kwargs)
            temp.parent = self
            self.leftChild = temp
        else:
            temp = BinaryTree(key, val, **kwargs)
            self.leftChild.parent = temp
            temp.leftChild = self.leftChild
            temp.parent = self
            self.leftChild = temp

    def insertRightChild(self, key, val, **kwargs):
        if self.rightChild is None:
            temp = BinaryTree(key, val, **kwargs)
            temp.parent = self
            self.rightChild = temp
        else:
            temp = BinaryTree(key, val, **kwargs)
            self.rightChild.parent = temp
            temp.rightChild = self.rightChild
            temp.parent = self
            self.rightChild = temp

    def getRoot(self):
        return self.key, self.payload

    def setRootVal(self, key, val):
        self.key = key
        self.payload = val

    def getLeftChild(self):
        return self.leftChild
    
    def getRightChild(self):
        return self.rightChild

1.2 二叉树的遍历

对一个数据集中的所有数据项进行访问的操作称为遍历(Traversal),树的非线性特点,使得遍历操作较为复杂。按照对节点访问次序的不同,二叉树有三种常见遍历方式:

  1. 前序遍历(preorder):先访问根节点,再递归地前序访问左子树、最后前序访问右子树;
  2. 中序遍历(inorder):先递归地中序访问左子树,再访问根节点,最后中序访问右子树;
  3. 后序遍历(postorder):先递归地后序访问左子树,再后序访问右子树,最后访问根节点。

代码实现:
通过递归调用实现树的遍历十分简单,三种不同的遍历方式只需调整基本条件和递归调用的代码执行顺序即可。

# 二叉树前序遍历
def preorder(tree):
    if tree is not None:
        print(tree.payload)
        if tree.leftChild is not None:
            preorder(tree.leftChild)
        if tree.rightChild is not None:
            preorder(tree.rightChild)

# 二叉中序遍历
def inorder(tree):
    if tree is not None:
        if tree.leftChild is not None:
            preorder(tree.leftChild)
        print(tree.payload)
        if tree.rightChild is not None:
            preorder(tree.rightChild)

# 二叉树后序遍历
def postorder(tree):
    if tree is not None:
        if tree.leftChild is not None:
            preorder(tree.leftChild)
        if tree.rightChild is not None:
            preorder(tree.rightChild)
        print(tree.payload)

1.3 常见二叉树

常见的二叉树类型有平衡二叉树(Balanced Binary Tree)、完全二叉树(Complete Binary Tree)、满二叉树(Full Binary Tree)和二叉查找树(Binary Search Tree,也称:二叉搜索树或二叉排序树)四类。其中,二叉查找树和完全二叉树一定是平衡二叉树,满二叉树是完全二叉树的一个特例。他们之间的关系,如下图所示:

左右子树高度差<=1
节点按从左到右顺序逐层添加
按数据值大小填充到左/右子树
每层节点都已填充完全
应用于
应用于
应用于
二叉树
平衡二叉树
完全二叉树
二叉查找树
满二叉树
二叉堆
AVL树
  • 平衡二叉树:是一颗空树,或它的左右两个子树的高度差的绝对值不超过1,并且左右两个子树也都是一颗平衡二叉树;
  • 完全二叉树:树中所有节点均按从上至下、从左到右的顺序依次插入,如下图所示;
  • 满二叉树:当全完二叉树的每一层节点都已填充满,它就是满二叉树;
  • 二叉查找树:若其左/右子树不为空,则左子树上所有节点的值均小于其父节点的值、右子树上所有节点的值均大于其父节点的值,且其左/右子树也须为二叉查找树。

完全二叉树

图:完全二叉树

完全二叉树中节点有序插入,所以树节点序号与列表索引一致,那么 可通过非嵌套列表直接实现完全二叉树的数据结构。完全二叉树索引序号从1开始,所以实现该数据结构时:采用一个列表来保存节点数据,且列表首位索引为的元素置空,树节点数据从列表第二位(索引为1的位置)开始插入。由此, 若完全二叉树中某节点的下标为p,那么其左子节点的下标为2p、右子节点的下标为2p+1、其父节点的下标为p//2

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值