【算法】堆排序以及应用

一、堆性质

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<heapSize && array[index]<array[left])
            largest = left;
        if(right<heapSize && array[largest]<array[right])
            largest = right;
        if(largest!=index) {
            int temp = array[largest];
            array[largest] = array[index];
            array[index] = temp;
            adjustHeap(array, largest, heapSize); //递归调整
        }
    }

    /**
     * 建立堆
     * @param array  待建堆序列
     */
    public static void buildHeap(int array[]){
        for(int i=array.length/2-1;i>=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元素的小顶堆,每次从剩下的数里面取插入,如果比堆顶小则不比较,如果比堆顶大则相比较调整堆。大顶堆虽然也可以,但是浪费了堆的性质,不能像小顶堆一样减少比较的次数。


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值