HuaPu在学:Python数据结构与算法【二叉树】

本文介绍了树的基本概念,包括节点、度、层次等,并重点剖析了二叉树的特性,如概念、性质及实现方法,如广度优先和深度优先遍历。讨论了二叉树的种类如二叉搜索树、完全二叉树等,以及它们在Python中的应用实例。
摘要由CSDN通过智能技术生成


前言

以下是花圃在学习Python的数据结构与算法的一些要点内容笔记。


一、树

1.概念

树(tree)本身就是一种抽象的数据结构(ADT),树是一种非线性的数据结构,它是由n (n>=0)个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树,也就是说它是根朝上,而叶朝下的。特点是:

每个节点都有零个或者多个子节点
没有父节点的节点称之为根节点
每一个非根节点有且只有一个父节点
除了根节点之外,每个子结点可以分出多个不相交的子树

2.术语

在这里插入图片描述

节点的度:一个节点含有子树的个数(实际上来说就是一个节点的子节点的个数有多少)
树的度:一棵树之中最大的节点的度称之为树的度

叶节点:度为零,也就是不再有子节点的节点
父节点:有一个节点含有子节点,该节点称此节点的父节点
子节点:一个子树含有的根节点称之为该节的子节点
兄弟节点:具有相同父节点的节点

节点的层次:从根开始,根为第一层,根的子节点称之为第二层,根的子节点的子节点称之为第三层依次类推
树的高度或深度:树中节点最大的层次

堂兄弟节点:上上节点同
节点的祖先:该节点一直到根的线路上的所有节点
子孙:以某一节点为根的子树的任意节点
森林:互不相交的多棵树称森林

3.种类

(1)无序树
(2)有序树
Ⅰ二叉树
①完全二叉树
②满二叉树
③平衡二叉树
④排序二叉树
Ⅱ霍夫曼树
ⅢB树
在这里插入图片描述

4.数据存储

顺序存储
在这里插入图片描述

链式存储
在这里插入图片描述
在这里插入图片描述

二、二叉树

1.概念、性质

二叉树的概念其实就是对于每一个节点最多有两个子节点
二叉树的性质:
①在深度为K的二叉树中,最多存在2^k -1个节点

②在第K层中,该层最多有2^(k-1)个节点

③假设树结构中边的个数为x,树节点的个数为n,他们之间的关系是x=n-1,通过这个可以推出,度为2的节点(N2)和度为0的节点(N0)之间的关系:N0=N2+1

2.实现

**广度优先遍历:**广度优先遍历实际上是在同层次之间开展的,利用的是队列的概念,思路是这样的,首先我队列中去添加我的根节点地址,通过弹出的方式取出此时元素(那一段是头自己定,顺序不要乱),判断他的左孩子是否为空,为空直接添加元素到这个位置然后直接return去返回结束(因为后面涉及判断右孩子),不是空将左孩子追加到我的队列中,注意从一开始弹出的另一端去追加,比如弹出头部,那你就要追加在尾部,不为空(遍历的话,就需要在弹出的时候打印出来);判断右孩子是否为空,为空直接挂元素,return返回,不为空就直接在队列中追加元素。整个过程直到我的队列为空,结束。

# 定义节点:
class Node(object):
    def __init__(self,item):
        self.elem=item
        self.rchild=None
        self.lchild=None
        pass
    pass

# 定义连接关系:
class Tree(object):
    def __init__(self):
        self.__root=None
        pass

    def add(self,item):
        node=Node(item)
        if self.__root is None:
            self.__root=node
            return
        queue=[self.__root]
        while queue:
            cur_node=queue.pop(0)
            if cur_node.lchild is None:
                cur_node.lchild=node
                return
            else:
                queue.append(cur_node.lchild)
                pass
            if cur_node.rchild is None:
                cur_node.rchild=node
                return
            else:
                queue.append(cur_node.rchild)
                pass
        pass
    def bread_travel(self):
        queue=[self.__root]
        while queue:
            cur_node=queue.pop(0)
            print(cur_node.elem)
            if cur_node.lchild is not None:
                queue.append(cur_node.lchild)
                pass
            if cur_node.rchild is not None:
                queue.append(cur_node.rchild)
                pass
            pass
        pass
    pass

if __name__=="__main__":
    tree=Tree()
    tree.add(1)
    tree.add(2)
    tree.add(3)
    tree.bread_travel()

深度优先遍历:
先序遍历:根节点–》左树–》右树
中序遍历:左树–》根节点–》右树
后序遍历:左树–》右树–》根节点
【以上三种起始先中后看的是根节点的位置】
在这里插入图片描述

# 定义节点:
class Node(object):
    def __init__(self,item):
        self.elem=item
        self.rchild=None
        self.lchild=None
        pass
    pass

# 定义连接关系:
class Tree(object):
    def __init__(self,root=None):
        self.__root=root
        pass

    def add(self,item):
        node=Node(item)
        if self.__root is None:
            self.__root=node
            return
        queue=[self.__root]
        while queue:
            cur_node=queue.pop(0)
            if cur_node.lchild is None:
                cur_node.lchild=node
                return
            else:
                queue.append(cur_node.lchild)
                pass
            if cur_node.rchild is None:
                cur_node.rchild=node
                return
            else:
                queue.append(cur_node.rchild)
                pass
        pass
    def bread_travel(self):
        queue=[self.__root]
        while queue:
            cur_node=queue.pop(0)
            print(cur_node.elem,end=" ")
            if cur_node.lchild is not None:
                queue.append(cur_node.lchild)
                pass
            if cur_node.rchild is not None:
                queue.append(cur_node.rchild)
                pass
            pass
        pass
    def deep_preorder(self,node):
        if node is None:
            return
        print(node.elem,end=" ")
        self.deep_preorder(node.lchild)
        self.deep_preorder(node.rchild)
        pass

    def deep_midorder(self,node):
        if node is None:
            return
        self.deep_midorder(node.lchild)
        print(node.elem,end=" ")
        self.deep_midorder(node.rchild)
        pass

    def deep_postorder(self,node):
        if node is None:
            return
        self.deep_postorder(node.lchild)
        self.deep_postorder(node.rchild)
        print(node.elem,end=" ")
        pass

    pass

if __name__=="__main__":
    tree=Tree()
    tree.add(0)
    tree.add(1)
    tree.add(2)
    tree.add(3)
    tree.add(4)
    tree.add(5)
    tree.add(6)
    tree.add(7)
    tree.add(8)
    tree.add(9)
    tree.bread_travel()
    print()
    tree.deep_preorder(tree._Tree__root)
    print()
    tree.deep_midorder(tree._Tree__root)
    print()
    tree.deep_postorder(tree._Tree__root)
0 1 2 3 4 5 6 7 8 9 
0 1 3 7 8 4 9 2 5 6 
7 3 8 1 9 4 0 5 2 6 
7 8 3 9 4 1 5 6 2 0 

如何通过遍历去确定一棵树
要确定一棵树,一定要有中序,无论是先序+中序,还是中序+后序。原因在于中序是左根右,根将左右分开。

例如:先序+中序

0 1 3 7 8 4 9 2 5 6 
7 3 8 1 9 4 0 5 2 6 

先序是 根 左 右
中序是 左 根 右
【0】 1 3 7 8 4 9 2 5 6 0就是根节点,其余部分是左树+右树
7 3 8 1 9 4 【0】 5 2 6 0左侧就是左树,右侧就是右树
所以
【0 】1 3 7 8 4 9 2 5 6 ------》【0】 【1 3 7 8 4 9】 【2 5 6】
所以
左树的根就是1,右树的根就是2
所以
【7 3 8 【1】9 4 】【 0】 【5【2】 6】
所以对于中序的——9 4和先序的——49——就是4为根,9为左孩子


在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值