二叉搜索树:堆:最大堆的建立,插入和删除

前面我们讲到栈和队列的时候,这两种数据结构都是按时间的先后顺序来排列,如栈是按先进后出(FILO),后入先出的原则排列。而队列是按先进先出(FIFO)的原则排序。但有时候按这种时间原则的数据结构不能满足用户的一些需求,例如CPU需要执行程序的优先级别,很多时候不能靠时间顺序,有些程序重要性更高的时候,应该优先被调用,所以应该用一种按优先级高低来排列的数据结构,数据结构中的每一个对象都有各自的优先级,我们从这个结构序列中取出元素的原则是按优先级的高低来取出,而不是进入队列的先后顺序。这里就要用到一种数据结构:堆。如果我们要用二叉搜索树来实现堆这一结构,怎么做?

这里举例用最大堆,最大堆的二叉搜索树结构是,从根结点开始,每一个结点的优先级都比它的左右子树高。这样来实现的话,我们可以把二叉搜索树用一种平衡的,排好序的结构来存储从而提高后面操作的效率,那就是用完全二叉树。

堆最重要的特点就是结构有序性。用完全二叉树的结构,有序性分两种,一种是最大堆,也就是从根结点开始,任一结点的元素优先级都比它的左右子树高。第二种是最小堆,也就是从根结点开始,任一结点的元素优先级都比它的左右子树低。

那么对于堆的操作,最基本的有建堆,插入和删除三种。

最大堆的结构:

二叉搜索树:堆:最大堆的建立,插入和删除_第1张图片

先说删除,因为最大堆的建立方法和删除是相似的

二叉搜索树:堆:最大堆的建立,插入和删除_第2张图片

首先定义两个下标变量MaxHead用来下面找插入点,然后一开始判断堆空不空,空就直接结束了。删除的方法就是删除根结点后,在树的最后一个元素替换上来根结点的位置,最后一个元素在H->HeapArr[NowSize]的位置。接下来程序的循环就是找出这个最后一个元素应该换到树的哪一个位置上。首先让Head=1,也就是从根结点开始,也就是假设根结点被删除后,最后一个元素就是插在根结点上。接下来就是判断这个元素插到根结点后,有没有左右子树,根据下标来判断的话,Head*2就是左右子树的下标,如果有,就从左右子树里选一个较大的,和这个插入的元素作比较。最后找出最大的,把它插入到DeleteItem的位置上,这样就能保持插入后最大堆的有序性了。

接着是插入。

二叉搜索树:堆:最大堆的建立,插入和删除_第3张图片

按顺序插入,所以每次要插入的元素都放在数组的最后,就是i=++H->NowSize的地方。插入后,还要调整结点保持有序性,也就是保证每个结点都比其左右子树大。所以插入后还要用个循环来做比较,插入后的结点(i为下标位置)和它的父结点i/2,比较,如果结点比它的父结点大,就要调整位置,把父结点的值赋给i的位置的结点,然后把要插入的元素的值赋给父结点的位置。

最后是最大堆的建立,方法和删除操作相似。

二叉搜索树:堆:最大堆的建立,插入和删除_第4张图片

在按顺序插入完所有元素后,从最后一个元素开始和其父结点作比较。定义一个X来保存最后一个元素,然后和父结点比较,大的就往上移,最后调整出一个有序的堆。

二叉搜索树:堆:最大堆的建立,插入和删除_第5张图片

你可能感兴趣的:(C/C++,二叉搜索树,堆,数据结构)