[数据结构] 二叉堆,堆排序,优先级队列
2017-04-29 10:45
337 查看
前言
最近在看算法导论中的第六章堆排序,忍不信手又痒了起来,利用零散时间,参照书里的思路,利用java实现了一些堆的基本操作,供小白参考。
有时间会整理堆的介绍和一些性质,这事后话。
我也是菜鸟一个,代码中难免有bug,也请大手子交流与指出
源码
package com.jianglei; import java.util.ArrayList; import java.util.List; /** * 参照算法导论实现的二叉堆结构 * Created by Administrator on 2017/5/3. */ public class HeapSort<E extends Comparable<E>> { /** * 用ArrayList作为空器的底层存储 */ private List<E> elements = new ArrayList<>(); /** * 堆的元素数量 * @return */ public int size(){ return elements.size(); } /** * 在堆的末尾添加元素(测试用) * @param e * @return */ public boolean add(E e){ return elements.add(e); } /** * 返回此索引的左孩子的索引 * @param i * @return */ private int left(int i){ int leftIndex = 2 * i + 1; return leftIndex < size() ? leftIndex : -1; } /** * 返回此索引的右孩子的索引,如果为-1表示没有 * @param i * @return */ private int right(int i){ int rightIndex = 2 * i + 2; return rightIndex < size() ? rightIndex : -1; } /** * 返回此索引的双亲结点的索引,如果为-1表示没有 * @param i * @return */ private int parent(int i){ int parentIndex = (i - 1) / 2; return parentIndex < 0 ? -1 : parentIndex; } public String toString(){ return elements.toString(); } /** * 假设此节点的左子树,和右子树都满足二叉堆的性质,而以此索引为节点可能不满足二叉堆的性质, * 此方法调整该节点为根的树满足二叉堆的性质 * @param i */ public void maxHeapify(int i){ int largest = i; int left = left(i); int right = right(i); if(left != -1 && less(i, left)){ largest = left; } if(right != -1 && less(largest, right)){ largest = right; } if(largest != i){ exch(i, largest); maxHeapify(largest); } } /** * 将随机分配的列表调整为满足二叉堆性质的列表 */ public void buildMaxHeap(){ int lastInnerNodeIndex = lastInnerNodeIndex(); for(int i = lastInnerNodeIndex; i >= 0; i--){ maxHeapify(i); } } /** * 堆排序,此实现与算法导论里的描述有差异,并不推荐作为参考 * @return */ public List<E> heapSort(){ int end = size() - 1; List<E> list =new ArrayList<>(); buildMaxHeap(); for(int i = end; i >= 1; i--,end--){ exch(0,end); E e = remove(end); list.add(0, e); maxHeapify(0); } return list; } //最大优先级队列的一些操作 /** * 返回值最大的的节点 * @return */ public E heapMaximum(){ return get(0); } /** * 删除并返回值最大的节点,并重新构造最大堆 * @return */ public E heapExtractMax(){ if(size() == 0){ throw new IndexOutOfBoundsException(); }else if(size() == 1){ return get(0); }else{ E max = get(0); set(0, remove(size() - 1)); maxHeapify(0); return max; } } /** * 将某节点的值增大,并重新构造最大堆 * 如果key值比原节点值小则抛出异常{@code IllegalArgumentException} * @param i * @param key * @throws IllegalArgumentException */ public void increaseKey(int i, E key){ if(key.compareTo(get(i)) < -1){ throw new IllegalArgumentException("key is less than now"); } elements.set(i, key); while (i > 0 && elements.get(parent(i)).compareTo(elements.get(i)) < 0){ exch(i, parent(i)); i = parent(i); } } /** * 添加一个节点,并重新构造最大堆,将此节点调用至相应的位置 * @param key */ public void maxHeapInsert(E key){ add(key); int i = size() - 1; while (i > 0 && elements.get(parent(i)).compareTo(elements.get(i)) < 0){ exch(i, parent(i)); i = parent(i); } } //一些辅助函数 public E remove(int index){ return elements.remove(index); } private int lastInnerNodeIndex(){ return size() / 2; } private void exch(int i, int j){ E temp = get(i); set(i, get(j)); set(j, temp); } public void set(int i, E e){ elements.set(i, e); } public E get(int i){ E e = elements.get(i); return e; } public boolean less(int i, int j){ E e = get(i); E e1 = get(j); int compRes = e.compareTo(e1); return compRes < 0 ? true : false; } }
参考
算法导论相关文章推荐
- 【数据结构】用模版实现大小堆、实现优先级队列,以及堆排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 数据结构(5)优先级队列与堆排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 经典算法和数据结构(一) 优先级队列与堆排序
- 数据结构—堆排序及其应用(优先级队列)
- 【数据结构】堆,堆实现优先级队列,堆排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 数据结构之优先级队列(二叉堆)
- 【数据结构】用模版实现大小堆、实现优先级队列,以及堆排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 浅谈算法和数据结构(5):优先级队列与堆排序
- 浅谈算法和数据结构: 五 优先级队列与堆排序
- 《算法导论》第6章 堆排序 (2)优先级队列
- 优先级队列(二叉堆)
- 数据结构 二叉堆 & 堆排序