python实现二叉树(二)

二叉树作为最常用的数据结构,其主要应用有:二叉搜索树、平衡二叉树、堆、红黑树。接下来对以上四种二叉树进行说明。

目录

1. 二叉搜索树(Binary Search Tree,BST)

1.1 查找

1.2 查找最值

1.3 插入

1.4 删除

2. 平衡二叉树

2.1 插入

2.2 删除

3. 堆(Heap)

3.1 创建最大堆 

3.2 堆的插入

3.3 堆的删除

1. 二叉搜索树(Binary Search Tree,BST)

查找是数据结构中常用的操作,所谓查找就是根据给定的项item,从集合中找出与给定项item相同的记录。查找的算法有多种,二分查找是效率较高的查找方式。二分查找的原理如下:

         

查找分为静态查找和动态查找,所谓静态查找是指集合中的记录是固定的,没有删除和插入的操作,只能进行查找。很显然,二分查找就是静态查找的一种方式;所谓动态查找是指集合中的记录是动态变化的,不仅有较高的查找效率,对插入和删除操作也有较高的效率。那么针对于动态查找数据应该如何组织呢,二叉搜索树就是动态查找的数据存储方式。

二叉搜索树也称为二叉查找树,它在二叉树上施加了排序的顺序,一棵非空二叉搜索树有以下性质:

非空左子树所有节点数据项小于其根节点的数据项;非空右子树所有节点数据项大于其根节点的数据项;左右子树都是二叉搜索树。

满足以上性质的二叉树都是二叉搜索树,下图两个树结构都是二叉搜索树

                      

1.1 查找

若二叉搜索树为空,则返回None;若二叉搜索树不为空,则比较根节点数据项与要查找的项item的值:

如果查找项item大于根节点数据项root.data,则在根节点的右子树进行搜索;如果查找项item小于根节点数据项root.data,则在根节点的左子树进行搜索;如果查找项item和节点数据项相等,则返回该节点。

                                                         

以上面的二叉搜索树为例,其代码实现如下:

          

二叉搜索树的查找效率取决于树的高度 

1.2 查找最值

查找二叉搜索树的最大值或最小值,因为二叉搜索树是排序顺序的,由二叉搜索树的性质可以,树中数据的最小值就是最左边的节点的数据项;而树中数据的最大值是最右边节点的数据项。如下图所示,最小值3位于树最左边的节点;最大值位于树最右边的节点。

                                           

 最小查找的代码如下:

             

最大查找的代码如下:

              

1.3 插入

插入操作的关键是找出元素要插入的位置,可以采取类似于查找的方法,判断当前节点数据项和要插入元素的大小以确定要插入元素的位置,对于BST通过中序遍历会得到从小到大排列的节点数据元素。具体程序如下:

1.4 删除

删除操作是BST中最复杂的操作,BST的删除操作的分析如下:

        

          

二叉搜索树的删除操作的代码实现如下: 

        

至此,有关二叉搜索树插入、查找、查找最值、删除操作就完成了, BST对插入和删除也有着较高的效率。

2. 平衡二叉树

平衡二叉树又称为AVL树,它是一种平衡二叉搜索树,其名字发明者的名字( Adelson-Velskii 以及 Landis)。其左右子树的高度差不大于1;每个子树均为AVL树。

在AVL树中引入了一种名叫“平衡因子(Balance Factor,BF)”的监督机制,平衡因子是这么定义的:每个节点的左子树的高度与右子树高度的差值。因为,我们可以借助平衡因子来定义AVL树:所有的节点的平衡因子的绝对值都不大于1的二叉树即为AVL树。

给定节点数为n的AVL树的最大高度为:{\color{Red} O(log_{2}n)}

AVL树的查找以及查找最值是和BST是一样的,在此不再进行赘述。接下来着重说明平衡二叉树的插入操作。

2.1 插入

插入操作可能会破坏AVL树的平衡,有四种插入情况会破坏AVL树的平衡,分别如下:

    

 对于第一种情况:在右子树的右边插入元素破坏AVL树的平衡,我们需要定义一个右单旋函数,如下:

     

同样的其他三种旋转函数的定义如下:

     

定义了旋转函数后,接下来就可以定义插入函数了,插入函数中调用了以上四个旋转函数,具体实现如下:

   

接下来,分别创建上面的理论讲解中的四棵AVL树,并向其中插入指定元素,最后对插入元素后的前序进行遍历并打印树的高度,具体测试代码如下:

    

2.2 删除

同样的,删除操作也有可能会导致AVL平衡破坏,而且删除的节点有三种情况(有两个子节点、只有一个子节点、叶子节点),综合BST中的删除操作以及AVL树中的旋转操作得到AVL的删除操作如下:

接下来通过创建一棵AVL树然后对其进行删除操作的测试代码如下:

  

至此,关于AVL树的相关操作已经完成。 

3. 堆(Heap)

这里的堆和堆栈是两种不同的概念,在说到堆之前,我们先回忆一下队列,队列是按照时间上先进先出的方式来组织数据的,但是就像买火车票有军人优先窗口一样,有一种特殊的队列,它取出元素的顺序是按照元素的优先权(关键字)大小,而不是元素入队的先后顺序。我们知道,队列是一种线性结构,我们可以使用数组、链表来实现队列,但是数组和链表进行删除和插入操作的复杂度较高,那么有没有更好的数据结构来实现优先队列组织数据呢。答案是肯定的,我们可以采用树结构来实现优先队列。如下图:

    

从上图中可以看到,堆是一种树结构,更一般的,堆是完全二叉树。接下来以最大堆为例,对堆的创建、插入删除等操作进行说明。

3.1 创建最大堆 

 

3.2 堆的插入

 

3.3 堆的删除

4 红黑树

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值