最大堆建堆过程的优化及第二种堆排序【Java版】

*最大堆建堆过程的优化
*与上条博客区别在于构造函数,heapify过程,具体来说:

public class MaxHeap {
    private int count;  //记录堆中存储元素的个数
    private static int[] data; //用数组存储二叉堆
    private int capacity;
//***********************
    //heapify过程
    //新建一个构造函数
    public MaxHeap(int[]arr,int n) {
        //data索引从1开始
        data=new int[n+1];
        for(int i=0;i<n;i++) {
            data[i+1]=arr[i];
        }
        count=n;
        // i=count/2,data数组中第一个不是叶子的节点
        //叶子节点看成满足堆
        //根节点从1开始
        //此时构造方法已经实现了一个堆,不需要shiftUp,但是不能插入
        for(int i=count/2;i>=1;i--) {
            shiftDown(i);
        }
    }
//*****************************************
    //判断堆是否为空
    boolean isEmpty() {
        return count==0;
    }
    //输出堆中元素个数
    int size() {
        return count;
    }
    public int getCapacity() {
        return this.capacity;
    }
    //从堆中取出元素,优先队列思想
    public int extractMax() {
        if(count<=0)
            return 0;
        //先取出最大的(优先级高的)
        int max=data[1];
        //将堆中最后一个元素存入第一元素的位置
        swap(1, count);
        count--;
        //将第一个元素向下移,找到合适位置,维护堆
        shiftDown(1);
        return max;
    }
    private void shiftDown(int i) {
        //定义左孩子,完全二叉树如果有孩子,一定有左孩子
        while (2*i<=count) {
            int j=2*i;
            //j+1即为右孩子
            if(j+1<=count&&data[j+1]>data[j])
                j+=1;
            if(data[i]>=data[j])
                break;
            swap(i, j);
            i=j;
        }       
    }
    private void swap(int i, int j) {
        if(i!=j) {
            int temp=data[i];
            data[i]=data[j];
            data[j]=temp;
        }

    }
    public void print(int []data,int count) {
        for(int i=0;i<=count;i++)
            System.out.print(data[i]+" ");

        System.out.println();
    }
}

*第二种堆排序
*时间复杂度和空间复杂度均为O(n)
*第一种是将n个元素逐个插入到一个空堆中,所以为O(nlogn)
*优化方式只利用shiftDown,为O(n)

public class HeapSort1 {
    public void heapSort2(int[]arr,int n) {
        //此时已经实现一个堆,heapify过程
        MaxHeap heap2=new MaxHeap(arr,n);
        //从小到大排序
        for(int i=n-1;i>=0;i--) {
            arr[i]=heap2.extractMax();
        }
    }
    public static void main(String[] args) {
        int [] arr= {8,7,4,5,9,2,10,3,3,3,30,3};
        int n=arr.length;

        HeapSort1 sort2=new HeapSort1();
        sort2.heapSort2(arr, n);        
        for(int i=0;i<n;i++)
            System.out.print(arr[i]+" ");
    }
}

猜你喜欢

转载自blog.csdn.net/yulutian/article/details/79596234