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
原创粉丝点击