堆排序
程序员文章站
2022-05-24 08:48:33
...
/** * <ul> * <li>平均情况:O(nlog(2)n)</li> * <li>最好情况:O(nlog(2)n)</li> * <li>最坏情况:O(nlog(2)n)</li> * <li>辅助存储:O(1)</li> * <li>不稳定</li> * <ul> * * @timestamp Mar 12, 2016 6:56:54 PM * @author smallbug */ public class HeapSort { public static void main(String[] args) { int[] data = DataUtil.getData(50); System.out.println(Arrays.toString(data)); long time = System.currentTimeMillis(); heapSort(data); System.out.println(Arrays.toString(data)); System.out.println("speed " + (System.currentTimeMillis() - time) + " ms"); System.out.println("排序是否成功:" + (DataUtil.verify(data, DataUtil.ASC) ? "是" : "否")); } private static void heapSort(int[] data) { createHeap(data); heapSortDetail(data); } private static void heapSortDetail(int[] data) { // 末尾与头交换,交换后调整最大堆 for (int i = data.length - 1; i > 0; i--) { int temp = data[0]; data[0] = data[i]; data[i] = temp; maxHeapify(data, i, index2Cood(0)); } } private static void createHeap(int[] data) { int startIndex = getParentIndex(data.length); for (int i = startIndex; i >= 0; i--) { maxHeapify(data, data.length, index2Cood(i)); } } private static void maxHeapify(int[] data, int heapSize, int cood) { // 当前点与左右子节点比较 int leftIndex = getChildLeftIndex(cood); int rightIndex = getChildRightIndex(cood); int largest = cood; if (leftIndex < heapSize && data[cood2Index(cood)] < data[leftIndex]) { largest = index2Cood(leftIndex); } if (rightIndex < heapSize && data[cood2Index(largest)] < data[rightIndex]) { largest = index2Cood(rightIndex); } // 得到最大值后可能需要交换,如果交换了,其子节点可能就不是最大堆了,需要重新调整 if (largest != cood) { int temp = data[cood2Index(cood)]; data[cood2Index(cood)] = data[cood2Index(largest)]; data[cood2Index(largest)] = temp; maxHeapify(data, heapSize, largest); } } /** * 索引转坐标 * * @timestamp 2016年8月23日 上午11:12:01 * @param index * @return */ private static int index2Cood(int index) { return index + 1; } /** * 坐标转索引 * * @timestamp 2016年8月23日 上午11:11:51 * @param cood * @return */ private static int cood2Index(int cood) { return cood - 1; } /** * 根据子元素坐标获取父元素索引 * * @timestamp 2016年8月23日 上午11:30:27 * @param cood * @return */ private static int getParentIndex(int cood) { return cood2Index(cood >>> 1); } /** * 左子节点position注意括号,加法优先级更高 * * @param current * @return */ private static int getChildLeftIndex(int cool) { return cood2Index(cool << 1); } /** * 右子节点position * * @param current * @return */ private static int getChildRightIndex(int cool) { return cood2Index(cool << 1) + 1; } }