堆排序

来源:互联网 发布:js deepCopy 编辑:程序博客网 时间:2024/04/27 23:41

堆排序

小弟初来咋到,面对算法一脸懵逼,希望各位大神能够给予指点,在此谢过。

简单的基于最大堆的优先队列

/** * Created by Fearless on 2017/3/30. */public class MaxPQ<T extends Comparable<T>> {    private T[] pq;//优先队列;    private int len = 0;//长度    public MaxPQ(int length) {        pq = (T[]) new Comparable[length + 1];    }    public boolean isEmpty() {        return len == 0;    }    public int size() {        return len;    }    public void insert(T v) {        pq[++len] = v;        swim(len);    }    public T delMax() {        T max = pq[1];//索引0处不放数据,所以最大的数据在索引1处        exch(1, len--);//将最大的数据放到最后,且将长度减一        pq[len + 1] = null;//将交换后的最后一个数据的位置置空        sink(1);//恢复堆的有序性        return max;//返回最大值    }    /***     * 自下而上的堆有序化操作     * @param i     */    private void swim(int i) {        /**         * 1该元素与其父节点中的元素做比较         * 2如果比父节点的元素大交换二者的位置,交换位置后重复步骤1,         * 直到父节点大于等于该节点,或已经是根节点         * pq[i] 的父节点是pq[i/2]         */        while (i  >= 1 && less(i / 2, i)) {            exch(i / 2, i);            i = i / 2;        }    }    /***     * 从上到下的堆有序化操作     * @param i     */    private void sink(int i) {        /**         *  1该元素与其子节点中的最大元素进行比较         *  2如果比最大的小交换二者的位置,交换位置后重复步骤1,         * 直到没有子节点或比其最大子节点大         *  pq[i] 的子节点分别为pq[2*i],pq[2*i+1]         *  选用最大子节点A做比较能够保证父节点B大于A就会大于B的所有子节点,         * 如果B小于A,A与B交换后仍能保证A大于此时的所有子节点         */        while ((2 * i) <= len) {            int j=2*i;            //如果有两个子节点,且右节点大于左节点,j等于右节点的索引            if(j<len&&less(j,j+1)) j++;            //如果大于最大的子节点,退出循环            if(!less(i,j)) break;            exch(i,j);            i=j;        }    }    /***     * 比较大小     * @param i     * @param j     * @return     */    private boolean less(int i, int j) {        return pq[i].compareTo(pq[j]) < 0;    }    /***     * 返回大的索引     * @param i     * @param j     * @return     */    private int max(int i, int j) {        if (pq[i].compareTo(pq[j]) > 0) {            return i;        } else {            return j;        }    }    /***     * 交换元素位置     * @param i     * @param i1     */    private void exch(int i, int i1) {        T temp = pq[i];        pq[i] = pq[i1];        pq[i1] = temp;    }}

堆排序

思路:利用最大堆的特点,其堆顶必定是整个堆中的最大值,依次取堆顶值,得到的数据就是有序的

import java.util.Arrays;/** * Created by Fearless on 2017/4/7. */public class StackSort {    private static Comparable[] a={5,87,96,44,58,32,25,1,77,69,36,44};//测试数组    public static void main(String ... args){        sort(a);    }    public static void sort(Comparable[] a){        System.out.println(Arrays.toString(a));        int length=a.length;        /*为了方便排序,新建辅助数组,将newA[0] 的位置空出来         *这样就可以通过index/2和index*2、index*2+1 方便的找到父节点和子节点         */        Comparable[] newA=new Comparable[length+1];        System.arraycopy(a,0,newA,1,length);        for(int i=length/2;i>0;--i){            sink(newA,i,length);        }        int j=0;        while (length>0){            //取当前堆中最大值赋给数组a            a[j++]=newA[1];            //将最大值放到最后一个节点上,并删除最后一个节点            exch(newA,1,length--);            //对剩下的数据进行有序化            sink(newA,1,length);        }        System.out.println("降序:"+Arrays.toString(a));        System.arraycopy(newA,1,a,0,a.length);        System.out.println("升序:"+Arrays.toString(a));    }    /***     * 从上到下有序化堆     * @param a     * @param i     * @param length     */    private static void sink(Comparable[] a, int i,int length) {        while((i*2)<=length){            int j=i*2;            if(j<length&&less(a[j],a[j+1])) j++;            if(!less(a[i],a[j])) break;            exch(a,i,j);            i=j;        }    }    /***     * 交换i,j位置     * @param a     * @param i     * @param j     */    private static void exch(Comparable[] a, int i, int j) {        Comparable temp=a[i];        a[i]=a[j];        a[j]=temp;    }    /**     * 比较     * @param i     * @param j     * @return     */    private static boolean less(Comparable i, Comparable j) {        return i.compareTo(j)<0;    }}

ps:找不到合适的画图工具,所以没有画出执行过程。。。

0 0
原创粉丝点击