堆排序

堆排序

二叉堆是一个数组,可以将其看成是一个近似的完全二叉树

最大堆 父节点>=子节点 根节点最大
最小堆 父节点<=子节点 根节点最小
下标:
*Parent(i)
return i/2;
Left(i)
return 2*i;
Right(i)
return 2*i+1;
*
等比数列求和公式:(a1(1-q^n))/((1-q))
注:高度为h的二叉堆 元素最多:2^(h+1)-1最少:2^h
过程:元素最多:20+21+22+…+2h=2^(h+1)-1
元素最少:20+21+22+…+2h-1+1=2^h

另:含有n各元素的堆的高度为lgn,向下取整
过程: 2^h <=n<=2^(h+1)-1<2^(h+1)h<=lgn

MAX-HEAPIFY(A,i)
l=Left(i)
r=right(i)
if l<=size and A[l]>A[i]
    largest=l
else
    largest=i
if r<=size and A[r]>A[largest]
    largest=r
if largest 不等于 i
    exchange A[i] with A[largest]   
    MAX-HEAPIFY(A, largest)

构造最大堆算法

BUILD-MAX-HEAP(A)
    heap.size = A.length
for i = A.length/2 downto 1
        MAX-HEAPIFY(A,i)

堆排序算法

HEAPSORT(A)
    BUILD-MAX-HEAP(A)
    for i=A.length downto 2
        exchange A[1] with A[i]
    heap.size = A.heap.size-1
MAX-HEAPIFY(A,1)        

java代码

import java.util.Random;

/**
 * 
 * 利用最大堆进行排序
 *
 */
public class Main {

    private static int N = 10;// 数组的大小
    static Random rand = new Random();

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        test_HeapSort();
    }

    private static void test_HeapSort() {
        // TODO Auto-generated method stub
        int[] A = new int[N+1];
        A[0]=-1;
        for (int i = 1; i <= N; i++) {
            A[i] = rand.nextInt(1000);
        }
        System.out.println("排序前:");
        print(A);

        HeapSort(A);

        System.out.println("排序后(升序):");
        print(A);
    }

    /**
     * 堆排序
     * @param A
     */
    private static void HeapSort(int[] A) {
        // TODO Auto-generated method stub
        Build_Max_Heap(A);
        int length=A.length-1;
        //每次将根节点与需要排序的最后一个数交换 后维持最大堆
        for(int i=length; i>1;i--){         
            int temp = A[i];
            A[i]=A[1];
            A[1]=temp;
            Max_Heapfy(A,1,--length);       
        }
    }
    /**
     * 构建最大堆
     * @param A
     */
    private static void Build_Max_Heap(int[] A) {
        // TODO Auto-generated method stub
        int length=A.length-1;
        for(int i=length/2;i>0;i--){
            Max_Heapfy(A, i, length);
        }
    }
    /**
     * 维持最大堆
     * @param A
     * @param i 从第i个元素开始维护
     * @param length  维持堆的数组长度
     */
    private static void Max_Heapfy(int[] A,int i,int length) {
        // TODO Auto-generated method stub
        int l=left(i);
        int r=right(i);
        int largest=0;
        if(l<=length && A[l]>A[i]){
            largest=l;
        }else{
            largest=i;
        }
        if(r<=length && A[r]>A[largest]){
            largest=r;
        }
        if(largest!=i){
            int temp = A[i];
            A[i]=A[largest];
            A[largest]=temp;
            Max_Heapfy(A,largest,length);
        }       

    }

    //父节点
    private static int parent(int i) {
        return i/2;
    }
    //左节点
    private static int left(int i) {
        return 2*i;
    }
    //右节点
    private static int right(int i) {
        return 2*i+1;
    }

    // 打印数组
    private static void print(int[] A) {
        // TODO Auto-generated method stub
        for (int i = 1; i < A.length; i++) {
            System.out.print(A[i] + "\t");
        }
        System.out.println();
    }
}

运行截图:
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值