堆排序实现

public interface Sort{
	public void sort(int[] arr);
	public void sortDesc(int[] arr);
}

package Sort.Function;

/**
 * 堆排序
 * 
 */
public class HeapSort implements Sort{

	@Override
	/**
	 * 大到小
	 */
	public void sortDesc(int[] arr) {
		doSort(arr, false);
	}

	@Override
	/**
	 * 小到大
	 */
	public void sort(int[] arr) {
		doSort(arr, true);
	}

	public void doSort(int[] arr, boolean asc) {
		if (arr == null) {
			return;
		}
		
		int maxIndex = arr.length - 1;

		// 先调整为最大堆/最小堆, 最大堆用来正序(小到大),最小堆用来反序(大到小)
		// 从最后一个子节点的父节点开始
		for (int i = (maxIndex - 1) / 2; i >= 0; i--) {
			adjustHeap(arr, i, maxIndex, asc);
		}

		// 调整之后 arr[0]为最大值/最小值
		for (int i = 0; i < arr.length; i++) {
			// 替换arr[0]和arr[最后一个位置],即将 最大的/最小的 放到数组最后边
			swapArray(arr, 0, maxIndex - i);

			// 调整第一个位置,再次调整为最大堆/最小值
			adjustHeap(arr, 0, maxIndex - i - 1, asc);
		}
	}

	/**
	 * 替换
	 * 
	 */
	private void swapArray(int[] b, int i, int j) {
		int tmp = b[i];
		b[i] = b[j];
		b[j] = tmp;
	}

	/**
	 * 从i元素向下调整,将最大的数提到i位置
	 * 
	 */
	public void adjustHeap(int[] arr, int i, int maxindex, boolean asc) {
		int parent = i;// 父元素下标
		int child = parent * 2 + 1;// 左子元素下标

		while (child <= maxindex) {
			// 根据排序方式(大序 小序) 从左右节点中选择更小或更大的
			if ((child + 1) <= maxindex && selectRightOne(arr, child, asc)) {
				child = child + 1;
			}

			// 是否需要替换父子节点
			if (needSwap(arr, parent, child, asc)) {
				swapArray(arr, parent, child);
			}

			// 向下一层
			parent = child;
			child = parent * 2 + 1;
		}
	}

	/**
	 * 正序 父节点小需要替换, 反序 父节点大需要替换
	 */
	private boolean needSwap(int[] arr, int parent, int child, boolean asc) {
		return asc ? arr[parent] < arr[child] : arr[parent] > arr[child];
	}

	/**
	 * 正序 挑选左右节点更大的那个, 反序,挑选小的
	 */
	private boolean selectRightOne(int[] arr, int child, boolean asc) {
		return asc ? arr[child] < arr[child + 1] : arr[child] > arr[child + 1];
	}
}
public class HeapSortTest{
	public static void main(String[] args) {
		int[] a = {4,1,9,15,1,12,3};
		
		Sort heapSort = new HeapSort();
	
		heapSort.sortDesc(a);// 堆排序asc
		printArr(a);
	}
	

	
	private static void printArr(int[] arr) {
		StringBuilder sb = new StringBuilder();
		for (int j = 0; j < arr.length; j++) {
			sb.append(" " + arr[j]);
		}
		System.out.println(sb.length() > 0 ? sb.substring(1) : sb.toString());
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值