排序算法之堆排序

package sort;

import java.util.Arrays;

public class HeapSort {

	public static void main(String[] args) {
		int[] a = {3,6,2,9,5,8,7,1,4};
		heapSort(a);
		System.out.println(Arrays.toString(a));
	}
	
 	/*堆排序,可认为是一种优化的选择排序,可分为两步
 	第一步建堆,第二步执行n-1次deleteMax
 	注意堆排序使用的堆和标准二叉堆略有不同,一是使用最大堆而不是最小堆;二是数据从数组下标0开始(二叉堆从1开始)*/
	public static void heapSort(int[] a){
		//buildHeap
		//a.length/2 - 1 是怎么得到的?在二叉堆中位置i的父节点是floor(i/2),因此在堆排序中是floor((i+1)/2)-1,
		//把i=a.length-1带入即得。
		for (int i = a.length/2 - 1; i>=0; i--)
			percDown(a, i, a.length);
		
		//deleteMax
		for (int i = a.length -1; i>0; i--){
			//注意下滤时堆在不断变小,即已经排好序的数虽然还在数组里但不属于堆的一部分
			swap(a, 0, i);
			percDown(a, 0, i);
		}
	}

	//核心方法——下滤
	//从位置i开始下滤,即“空穴”的位置。n是堆大小
	private static void percDown(int[] a, int i, int n) {
		//使用和插入排序相同的小技巧。不显式使用交换
		int tmp = a[i];
		
		while(leftChild(i) < n){
			int child = leftChild(i);
			//确定两个儿子中较大的那个
			if (child != n-1 && a[child] < a[child+1])
				child++;
			if (tmp < a[child])
				a[i] = a[child];
			else
				break;
			
			i = child;
		}
		a[i] = tmp;
		
	}

	private static int leftChild(int i) {
		return 2 * i + 1;
	}
	
	private static void swap(int[] a, int i, int j) {
		int tmp = a[i];
		a[i] = a[j];
		a[j] = tmp;
		
	}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值