【算法】堆排序以及应用

一、堆性质

n个关键字序列k1,k2,.........kn当且仅当满足一下性质是为一个堆

  • k[i]<=k[2i]
  • k[i]<=k[2i+1](1≤i≤ n/2)
以上是小顶堆的定义,大顶堆则相反吧<=改为大于等于即可。若将堆看成一颗二叉树,那么则树中任一非叶子结点的关键字均不大于(或不小于)其左右孩子(若存在)结点的关键字。

1、堆的构建

找到第一个非叶子节点,根据大顶堆或者小顶堆的性质进行调整,当前以及其左右子节点比较。
注意,被调整的节点,还有子节点的情况,需要递归进行调整。

2、堆的插入

插入节点时,先插入到最后,然后再调整堆

3、堆的删除

删除最小节点即删除根节点,先将根节点和最后一个节点交换,再调整堆。

二、堆排序

堆排序(Heapsort)是指利用堆积树(堆)这种数据结构所设计的一种排序算法,它是选择排序的一种。可以利用数组的特点快速定位指定索引的元素。堆分为大根堆和小根堆,是完全二叉树。大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。

package Sort;

/**
 * Created by LemonTree on 2017/4/5.
 */
public class HeapSort {

    /**
     * 调整堆
     * @param array  原始堆
     * @param index  调整位置
     * @param heapSize 堆大小
     */
    public static void adjustHeap(int[] array,int index, int heapSize){
        int left = 2*index+1;
        int right = 2*index+2;
        int largest = index;
        if(left=0;i--){
            adjustHeap(array,i,array.length); //如看成完全二叉树,那么则从树的第一个非叶子节点进行调整,顺序为array.length/2-1 ------>0,从后向前
        }
    }

    /**
     * 堆排序
     * @param array  堆排序
     */
    public static void sort(int[] array){
        buildHeap(array);
        for(int i=array.length-1;i>=0;i--){
            int temp = array[0];
            array[0] = array[i];
            array[i] = temp;
            adjustHeap(array,0,i);          //每次堆的大小递减
        }
    }

    public static void main(String[] args) {
        int[] array={9,3,4,6,1,2,3,45,6};
        sort(array);
        for(int num:array){
            System.out.print(String.valueOf(num)+"  ");
        }

    }
}

三、应用

题目:从1亿个数中求出最大的前100个数。

思路:建立一个100元素的小顶堆,每次从剩下的数里面取插入,如果比堆顶小则不比较,如果比堆顶大则相比较调整堆。大顶堆虽然也可以,但是浪费了堆的性质,不能像小顶堆一样减少比较的次数。


你可能感兴趣的:(数据结构,算法)