java实现最大堆及代码测试
来源:互联网 发布:疯狂的美工助手破解版 编辑:程序博客网 时间:2024/05/01 06:25
算法分析:
堆排序和归并排序一样,实践时间复杂度是O(nlgn),不同于归并排序的是,堆排序是一种原址排序。本文介绍最大堆。
代码中关键操作:
maxHepify:时间复杂度是O(lgn),是维护堆性质的关键。
buildMaxHeap:建立最大堆,时间复杂度是O(n);
heapSort:通过调用exactMax,按顺序得到一个排序的数组,时间复杂度是O(nlgn);
insert:插入新元素,通过调用increseKey私有方法操作,时间复杂度是O(lgn);
当然,还有max(),exactMax()方法。更加具体分析请参见《算法导论》,下面是我的实现代码和测试代码:
import java.lang.reflect.Array;import java.util.Arrays;import java.util.Comparator;// 逻辑上堆是从index = 1开始,实际上从index = 0开始,// 故各方法中常见index - 1;public class MaxHeap<T extends Comparable<T>> {Object[] array;private final int DEFAULT_CAPACITY = 100;private final float LOAD = 0.75F;private int size = 0;private Comparator<T> comparator;// 构建一个空堆public MaxHeap() {array = new Object[DEFAULT_CAPACITY];}// 构建一个堆,包含array中的数据,array初始容量是array长度两倍public MaxHeap(T[] array) {this(array, null);}// 构建一个堆,包含array中的数据,array初始容量是array长度两倍,并按提供的比较器大小比较public MaxHeap(T[] array, Comparator<T> comparator) {this.array = Arrays.copyOfRange(array, 0, array.length * 2);size = array.length;this.comparator = comparator;buildMaxHeap();}// 代理堆中对象的比较方法@SuppressWarnings("unchecked")private int compare(Object o1, Object o2) {if (comparator == null)return ((T) o1).compareTo((T) o2);elsereturn comparator.compare((T) o1, (T) o2);}// 使得初始化堆满足最大堆性质private void buildMaxHeap() {for (int i = size / 2; i >= 1; i--)maxHeapify(i);}// 假设i+1, i+2...已经满足最大堆性质,执行此方法后,// 使得i, i+1,i+2.....满足最大堆性质private void maxHeapify(int i) {int l = left(i);int r = right(i);int largest;if (l <= size && compare(array[l - 1], array[i - 1]) > 0)largest = l;elselargest = i;if (r <= size && compare(array[r - 1], array[largest - 1]) > 0)largest = r;if (largest != i) {swap(i, largest);maxHeapify(largest);}}// 交换i1,i2处的值private void swap(int i1, int i2) {Object temp = array[i1 - 1];array[i1 - 1] = array[i2 - 1];array[i2 - 1] = temp;}// 返回左孩子位置private int left(int parent) {return 2 * parent;}// 返回右孩子位置private int right(int parent) {return 2 * parent + 1;}// 返回父节点位置private int parent(int child) {return child / 2;}// 返回堆中最大值@SuppressWarnings("unchecked")public T max() {return (T)array[0];}// 返回并删除堆中最大值@SuppressWarnings("unchecked")public T exactMax() {if(size < 1)throw new IndexOutOfBoundsException("堆中没有元素");T max = (T)array[0];array[0] = array[size - 1];size = size - 1;maxHeapify(1);return max;}// 插入一个值,如果堆已达到负载,将堆容量扩大一倍public void insert(T obj) {array[size] = obj;size = size + 1;if((float)size / array.length >= LOAD) {array = Arrays.copyOfRange(array, 0, array.length * 2);}increseKey(size, obj);}// 按顺序返回堆中元素的数组,将堆变成空堆public T[] heapSort() {if(size == 0)return null;else {@SuppressWarnings("unchecked")T[] result = (T[])Array.newInstance(array[0].getClass(), size);int len = size;for(int i = 0; i < len; i++)result[i] = exactMax();return result;}}// 判断堆是否是空堆public boolean empty() {return size == 0;}// 增加堆中指定index处的数据private void increseKey(int i, T key) {if(compare(array[i - 1], key) > 0)throw new UnsupportedOperationException("新值不能比原值小");array[i - 1] = key;while(i > 1 && compare(array[parent(i) - 1], array[i - 1]) < 0) {swap(parent(i), i);i = parent(i);}}}
测试代码(其中涉及到的SortComparble和Point类,请参见我的上一篇博客:http://blog.csdn.net/qq_35328850/article/details/56279113):
import java.util.Arrays;import NearestPoints.Point;import NearestPoints.PointGenerator;import NearestPoints.PointYComparaotr;import NearestPoints.SortComparable;// SortComparble 已被确认正确public class TestMaxHeap {private static final int SIZE = 100;public static void main(String[] args) {// 生成点数组Point[] points = new Point[SIZE];for(int i = 0; i < points.length; i++)points[i] = new PointGenerator(1000).next();// 建立默认堆,并得到堆排序的数组heap1SortMaxHeap<Point> heap1 = new MaxHeap<>();for(int i = 0; i < points.length; i++)heap1.insert(points[i]);Point[] heap1Sort = heap1.heapSort();// 调用SortComparable,将points从小到大按默认比较方法排序SortComparable.sort(points);// 逐个比较SortComparble排序和MaxHeap排序结果,有不一致输出 “error”for(int i = 0; i < points.length; i++)if(!points[i].equals(heap1Sort[heap1Sort.length - i - 1]))System.out.println("error" + i + points[i] + heap1Sort[heap1Sort.length - i - 1]);// 建立有比较器的堆,并得到堆排序的数组heap2SortMaxHeap<Point> heap2 = new MaxHeap<>(points, new PointYComparaotr());Point[] heap2Sort = heap2.heapSort();// 逐个比较SortComparble排序和MaxHeap排序结果,有不一致输出 “error”SortComparable.sort(points, new PointYComparaotr());for(int i = 0; i < points.length; i++)if(!points[i].equals(heap2Sort[heap2Sort.length - i - 1]))System.out.println("error" + i + points[i] + heap2Sort[heap2Sort.length - i - 1]);}}
0 0
- java实现最大堆及代码测试
- java实现最大堆及堆排序
- 最大堆及堆排序的Java实现_world
- Java 实现最大堆
- 最大堆java实现
- 最大堆及堆排序的实现
- 最大堆及堆排序的实现
- 【算法】堆,最大堆(大顶堆)及最小堆(小顶堆)的实现【2】---软件截图及算法代码
- java实现最大堆数据结构
- java 实现构造最大堆
- 使用Java实现最大堆
- java实现最大索引堆(最大堆的优化版)
- 最大堆及优先队列的实现
- 堆排序原理及算法实现(最大堆)
- 堆排序原理及算法实现(最大堆)
- 堆排序原理及算法实现(最大堆)
- 堆排序原理及算法实现(最大堆)
- 堆排序原理及算法实现(最大堆)
- 【BZOJ 4445】[Scoi2015]小凸想跑步 半平面交
- debug的使用--必备
- HDU
- C++与运算(&)错误笔记(优先级)
- iOS信号量机制
- java实现最大堆及代码测试
- Android使用OkHttp实例,以及OkHttp方法封装
- 图像形态学操作—腐蚀膨胀深入
- appium的一个内存泄露bug
- HTML的表单元素和input元素
- IO
- Java编程题练习2017-02-22
- 【C++ STL 温故而知新 002】Lists(链表)
- restful架构