而为了维护堆的彻底性,就决定了堆插入结点时只有两种状况:html
1.h层的左边下一个位置。
2.h+1层的第一个位置。(h层为满)git
BinaryTreeNode类
,而且添加双亲指针和对应的set方法。有一个实例数据lastNode
做用是跟踪记录堆中的最后一个叶子,也就是指向末结点的引用。
算法
lastNode
指针从新设定为指向新的最末结点。addElement
操做的复杂度为2 * logn + 1 + logn,为O(logn)。removeMin
操做的复杂度为2 * logn + logn + 1,为O(logn)。根据书P268 和 P270,api
由于数组不须要肯定新结点双亲的步骤,以及数组不须要肯定新的最末结点。因此,虽然他的时间复杂度和用链表实现时是同样的,可是数组实现的效率更高一些。数组
首先,要清楚堆排序的思想,堆排序是一种选择排序 。如何将一个杂乱排序的堆从新构形成最大堆,它的主要思路就是数据结构
从上往下,将父节点与子节点以此比较。若是父节点最大则进行下一步循环,若是子节点更大,则将子节点与父节点位置互换,并进行下一步循环。注意父节点要与两个子节点都进行比较。学习
咱们第一步就应该明白,如何将一个无序列表构建成最大堆。优化
从最后一个非叶节点开始调整。.net
如图,这里的最后一个非叶子结点是结点4,那么咱们就从这里进行调整。设计
每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换以后可能形成被交换的孩子节点不知足堆的性质,所以每次交换以后要从新对被交换的孩子节点进行调整)。
如图,发现,我插入队列的依次是,2,10,3。而后中序遍历就是10,2,3。这是没有问题的,可是删除以后,虽然2删除掉了,可是多了一个3。
dequeue()
方法,调用了以前父类ArrayHeap
类中removeMin()
方法所引发的。CompareTo
方法的断定条件不一样。队列只须要将进入堆的顺序记录下来就能够而后比较便可。那么这里的调用的removeMin()
方法实际上就是删除队列中顺序最低的,也就是第一个进来的元素。public T removeMin() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException("ArrayHeap"); T minElement = tree[0]; tree[0] = tree[count-1]; heapifyRemove(); count--; modCount--; return minElement; }
tree[count] =null;就能够解决问题了。
堆是基于二叉树的。这周看代码的效率并非很高,对于代码的理解也不是很深刻。归结于学习积极性不高。凡事不要钻牛角尖,过去的就过去了,一切都会好起来。不要给本身额外的压力和负担。
看过别的同窗优秀的博客之后发现本身不能懈怠。好比不少同窗都联系到了上学期的堆栈内存时的学习内容。学习应该有体系,不可以东拼西揍,捡西瓜丢芝麻。仍是要踏实下来,戒骄戒躁。
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 0/0 | 1/1 | 10/10 | |
第二周 | 610/610 | 1/2 | 20/30 | |
第三周 | 593/1230 | 1/3 | 18/48 | |
第四周 | 2011/3241 | 2/5 | 30/78 | |
第五周 | 956/4197 | 1/6 | 22/100 | |
第六周 | 2294/6491 | 2/8 | 20/120 | |
第七周 | 914/7405 | 1/9 | 20/140 | |
第八周 | 2366/9771 | 2/11 | 22/162 |