树(一):二叉树的概念与基本操作

引言

本章将介绍非线性结构——二叉树,相对于之前的线性表、栈、队列等数据结构,二叉树中的元素有着更为复杂的联系,因此也存在更复杂的操作。

二叉树的概念

作为最简单的树形结构,二叉树中每个结点最多关联两个后继节点,且结点分为空、左、右。

官方定义:二叉树(binary tree)是指树中节点的度不大于2有序树,它是一种最简单且最重要的树。二叉树的递归定义为:二叉树是一棵空树,或者是一棵由一个根节点和两棵互不相交的,分别称作根的左子树和右子树组成的非空树;左子树和右子树又同样都是二叉树。
以下为二叉树的几个较为重要的概念:

  • 不包含任何结点的二叉树称为空树,只包含一个节点的二叉树称为单点树(类链表)

  • 一棵二叉树的根节点成为该树的子树根结点的父结点;与之对应,子树的根结点成为二叉树树根结点的子结点

  • 父结点到子结点的连线称为,方向为父→子

  • 基于父子关系可以定义其传递关系,称为祖先/子孙关系,它决定了一个结点的祖先节点/子孙结点;父结点相同的两个子结点称为兄弟结点

  • 如果一个结点不含有子结点,则称为

  • 一个结点的子结点个数称为,度不为0的结点称为分支结点

  • 从一个祖先节点到一个子孙结点都存在一系列边,这一系列边构成了树的一条路径,路径边的条数称为该路径的长度

  • 二叉树是一种层次结构,规定根节点的层次为1,其子结点看作下一层元素

  • 二叉树的最大层数为高度

基本性质

二叉树的性质如下:

  1. 在非空二叉树第i层中至多有2^i个结点

  2. 高度为h的二叉树至多有2^(h+1)-1

  3. 对于任何非空二叉树T,如果其叶结点的个数为n0,度数为2的结点个数为n2,那么n0=n2+1

特殊结构

二叉树的特殊结构主要有以下几种:

  • 满二叉树:如果二叉树中所有分支结点的度数都为2,则称它为一个满二叉树(如下图,图片来源,侵删);满二叉树叶子节点比分支节点多一个

  • 完全二叉树:除了最后一层以外,所有层都是满的(如下图,图片来源,侵删)

  • 扩充二叉树:将一个二叉树填入足够多的空叶子,使其原有结点都变为度为2的结点(如下图)。

二叉树的基本操作与实现

二叉树由结点构成,每个结点中存储着元素和指针域,而操作也是围绕于此进行,以下是二叉树的重要操作:

  • 创建二叉树

  • 判断是否为空树

  • 求二叉树的结点个数

  • 获取根节点的数据

  • 获取二叉树的左子树

  • 获取二叉树的右子树

  • 遍历二叉树(先序、中序、后序以及层序遍历)

Python实现:

from collections import deque

class BinaryTree():
    def __init__(self, val=None, left=None, right=None, height=0):
        self.val = val
        self.left = left
        self.right = right
        
    def preorder(self):
        if not self.val:
            return
        print(self.val, end=' ')
        if self.left:
            self.left.preorder()
        if self.right:
            self.right.preorder()
    
    def inorder(self):
        if not self.val:
            return
        if self.left:
            self.left.inorder()
        print(self.val, end=' ')
        if self.right:
            self.right.inorder()
    
    def postorder(self):
        if not self:
            return
        if self.left:
            self.left.postorder()
        if self.right:
            self.right.postorder()
        print(self.val, end=' ')
        
    def levelorder(self):
        if not self:
            return []
        d = deque([self])
        res = []
        while d:
            n = len(d)
            for i in range(n):
                node = d.popleft()
                res.append(node.val)
                if node.left:
                    d.append(node.left)
                if node.right:
                    d.append(node.right)
        return res
    
    def height_count(self):
        if not self:
            return 0 
        if not self.left and not self.right:
            return 1
        if self.left and not self.right:
            return self.left.height_count() + 1
        if not self.left and self.right:
            return self.right.height_count() + 1
        return max(self.left.height_count(), self.right.height_count()) + 1
    
    
class Solution:
    res = 0
    def maxDepth(self, root):
        tmp = 0
        self.DFS(tmp, root)
        return self.res

    def DFS(self, tmp, tree):
        if not tree:
            self.res = max(self.res, tmp)
            return
        tmp += 1
        self.DFS(tmp, tree.left)
        self.DFS(tmp, tree.right)
        
if __name__ == '__main__':
    tree1 = BinaryTree(3)
    tree2 = BinaryTree(6)
    tree3 = BinaryTree(1, tree1, tree2)
    tree4 = BinaryTree(2, tree2, tree1)
    root = BinaryTree(10, tree3, tree4)
    root.preorder()
    print('\n')
    
    root.inorder()
    print('\n')
    
    root.postorder()
    print('\n')
    
    print(root.levelorder())
    print('\n')
    
    print(root.height_count())

猜你喜欢

转载自blog.csdn.net/a159357445566/article/details/109138935
今日推荐