欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

堆排序

程序员文章站 2022-05-24 08:49:51
...
/**
 * <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;
	}
}