二叉树作为最常用的数据结构,其主要应用有:二叉搜索树、平衡二叉树、堆、红黑树。接下来对以上四种二叉树进行说明。
目录
1. 二叉搜索树(Binary Search Tree,BST)
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树的最大高度为:
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 红黑树