数据结构之堆排序(二)

马不停蹄,堆上昨晚 ---------堆的代码

public class Test {

	public static void main(String[] args) {
							
		Integer[] arr = {17, 9, 25, 21, 19, 12, 18, 23, 16, 15};
	    Heap.sort(arr);
	    System.out.println(Arrays.toString(arr));		
	}

  
}
public static calss Heap{
	//创建堆
    private static void createHeap(Comparable[] arr, Comparable[] heap){
     	System.arraycopy(arr, 0, heap, 0, arr.length);//将乱序数组拷贝到堆中
        //从最后一个下标开始倒着往第一个父节点按堆的规则排序,
        //父节点与两个子节点间只有两个数要做换位,因此只需要遍历长度的一半即可
        for(int i = heap.length / 2; i >= 0; i--){
            heapify(heap, i, heap.length - 1);
        }
    }
    //大顶堆的排序规则,两个子节点比父节点小 index当前要排序的节点下标, n未排序的范围
    private static void heapify(Comparable[] heap, int index, int n){
         // 左子节点的小标小于或等于未排序范围的话,说明有左子树      
        while((2 * index + 1) <= n ){
            //标记左子树或是右子树哪个更大
        	int max;
			//如果右子树小于未排序范围的话,说明有右子树
            if((2 * index + 2) <= n){
                //对比左子树与右子树元素的大小
                if(less(heap, 2 * index + 1, 2 * index + 2)) {
                	max = 2 * index + 2;//比较结果右子树大,标记为大的下标
                }else{
                	max = 2 * index + 1;//比较结果左子树大,标记为大的下标
                };
            }else{
                max = 2 * index + 1;//如果没有右子树,标记左子树为大的下标
            }
            if(!less(heap, index, max)){//当前节点大于最大小标,说明没有子节点则跳出循环
                break;
            }
            exch(heap, index, max);//将当前节点元素与标为最大下标元素换位
            index = max;//换位之后当前节点就是最大下标
        }
    }
    public static void sort(Comparable[] arr){
        Comparable[] heap = new Comparable[arr.length];//创建堆数组
        createHeap(arr, heap);//将数组放入堆中,生成一个按堆原则排列的堆
        int tail = heap.length - 1;//最后一个下标为堆的长度减一
        while(tail != 0){//堆的最后一个元素不是第一个元素
            exch(heap, 0, tail);//将大顶堆的最大元素放到最后一个下标处
            tail --;//按堆的小标顺序倒着排序
            heapify(heap, 0, tail);//按大顶堆规则再次将被打乱顺序的堆排序
        }
        System.arraycopy(heap, 0, arr, 0,arr.length);//将排好序的堆拷贝到数组上
    }
    private static boolean less(Comparable[] heap, int i, int j){
        return heap[i].compareTo(heap[j]) < 0;
    } 
    private static void exch(Comparable[] heap, int i, int j){
        Comparable temp;
        temp = heap[i];
        heap[i] = heap[j];
        heap[j] = temp;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值