addElement操做
将给定的元素添加到堆中的恰当位置,维持该堆的彻底性属性和有序属性。html
若是元素不是Comparable类型的,则会抛出异常。这是为了让元素可比较,能够维持堆的有序属性。java
public void addElement(T obj) { if (count == tree.length) expandCapacity(); tree[count] = obj; count++; modCount++; if (count > 1) heapifyAdd(); } private void heapifyAdd() { T temp; int next = count - 1; temp = tree[next]; while ((next != 0) && (((Comparable) temp).compareTo(tree[(next - 1) / 2]) < 0)) { tree[next] = tree[(next - 1) / 2]; next = (next - 1) / 2; } tree[next] = temp; }
removeMin操做
删除堆的最小元素:删除堆的最小元素而且返回。node
最小元素位于根结点,删除掉根结点,为了维持树的彻底性,要找一个元素来替代它,那么只有一个能替换根的合法元素,且它是存储在树中最末一片叶子上的元素。最末的叶子是h层上最右边的叶子。git
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; } /** * Reorders this heap to maintain the ordering property * after the minimum element has been removed. */ private void heapifyRemove() { T temp; int node = 0; int left = 1; int right = 2; int next; if ((tree[left] == null) && (tree[right] == null)) next = count; else if (tree[right] == null) next = left; else if (((Comparable) tree[left]).compareTo(tree[right]) < 0) next = left; else next = right; temp = tree[node]; while ((next < count) && (((Comparable) tree[next]).compareTo(temp) < 0)) { tree[node] = tree[next]; node = next; left = 2 * node + 1; right = 2 * (node + 1); if ((tree[left] == null) && (tree[right] == null)) next = count; else if (tree[right] == null) next = left; else if (((Comparable) tree[left]).compareTo(tree[right]) < 0) next = left; else next = right; } tree[node] = temp; }
public T findMin() throws EmptyCollectionException { if (isEmpty()) throw new EmptyCollectionException("ArrayHeap"); return tree[0]; }·
虽然最小堆根本就不是一个队列,可是它却提供了一个高效的优先级队列实现。api
heapifyAdd:完成对堆的任何重排序,从那片新叶子开始向上处理至根处数组
添加元素对于复杂度(复杂度为:2*logn + 1 +logn,即o(logn)):数据结构
heapifyRemove:进行重排序(从根向下)学习
删除根元素对于复杂度(复杂度为:2*logn + logn + 1,即o(logn))this
该元素在堆根处,只需返回根处便可.net
复杂度为o(1)
将count值递增1。
时间复杂度为 1 + log ,为 O(logn)。
返回初始的根元素,并将count值减1。
时间复杂度为 1 + log ,为 O(logn)。
指向索引为0
时间复杂度为O(1)。
例如
书中定义:
优先队列是一个服从两个有序规则的集合。首先,具备更高优先级的项排在前面。其次,具备相同优先级的项按先进先出的规则排列。
public void addElement(T obj) { HeapNode<T> node = new HeapNode<T>(obj); if (root == null) root = node; else { HeapNode<T> nextParent = getNextParentAdd(); if (nextParent.getLeft() == null) nextParent.setLeft(node); else nextParent.setRight(node); node.setParent(nextParent); } lastNode = node; modCount++; if (size() > 1) heapifyAdd(); }
其中有段代码: node.setParent(nextParent);
在add方法中已经明确代表nextParent.setLeft(node);
那设置node结点的父节点是newParent有什么意义?
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | |
---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 |
第一周 | 0/0 | 1/1 | 8/8 |
第二周 | 671/671 | 1/2 | 17/25 |
第三周 | 345/1016 | 1/3 | 15/40 |
第四周 | 405/1421 | 2/5 | 23/63 |
第五周 | 1202/2623 | 1/5 | 20/83 |
第六周 | 1741/4364 | 1/6 | 20/103 |
第七周 | 400/4764 | 1/7 | 20/123 |
第八周 | 521/5285 | 2/9 | 24/147 |