堆排序的java实现

堆排序是用大顶堆或者小顶堆的性质来实现排序。
先解释一下优先队列,优先队列就是从这个队列里面出来的数字总是这个队列里面数字最大或者最小的那一个,而堆就是一个优先队列的具体实现,大顶堆是一个完全二叉树,父节点大于等于子节点,所以他的顶(根)是最大的,小顶堆反之。
所以我们先实现一个大顶堆。

package sort;

/**
 * 使用二叉堆的优先队列,每个节点大于等于两个子节点
 * 并且是完全二叉树,每个节点的与数组的索引是一一对应的
 * @author asus
 *
 * @param <Item>
 */
public class MaxPQ<Item extends Comparable<Item>>
{
    private Item[] pq;
    private int size = 0;
    public MaxPQ()
    {
        pq = (Item[]) new Comparable[2];
    }
    public MaxPQ(int max)
    {
        pq = (Item[]) new Comparable[max + 1];
    }
    /**
     * 将数组存入pq形成优先队列,但不改变数组
     * @param a
     */
    public MaxPQ(Item[] a)
    {
        int len = a.length;
        pq = (Item[]) new Comparable[len + 1];
        for(int i = 1;i < len;i++)
        {
            pq[i] = a[i - 1];
        }
        pq[len] = a[len - 1];
        size = len;

        for(int i = size/2;i >= 1;i--)
        {
            sink(i);
        }

    }
    /**
     * 插入操作,先在二叉树尾部插入一个数
     * 再将这个数上浮
     * @param i
     */
    public void insert(Item i)
    {
        if(size == pq.length - 1)
            resize(pq.length*2);
        pq[++size] = i;
        swim(size);
    }
    /**
     * 删除最大的一个数
     * 将pq[1]也就是数的根与最后一个数交换
     * 再将新的根下沉
     * 最后返回原来的根
     * @return
     */
    public Item delMax()
    {
        Item t = pq[1];
        exch(1,size--);
        sink(1);
        pq[size+1] = null;
        return t;
    }
    public Item max()
    {
        return pq[1];
    }
    public boolean isEmpty()
    {
        return size == 0;
    }
    public int size()
    {
        return size;
    }
    private void swim(int k)
    {
        while(k > 1 && less(k/2,k))
        {
            exch(k,k/2);
            k = k/2;
        }
    }
    private void sink(int k)
    {
        while(2*k <= size)
        {
            int i = 2*k;
            if(i < size && less(i,i + 1))
                i++;
            if(less(k,i))
            {
                exch(k,i);
                k = i;
            }
            else break;
        }

    }
    private void exch(int i,int j)
    {
        Item temp = pq[i];
        pq[i] = pq[j];
        pq[j] = temp;
    }
    private boolean less(int i,int j)
    {
        return pq[i].compareTo(pq[j]) < 0;
    }
    private void resize(int max)
    {
        Item[] temp = (Item[]) new Comparable[max];
        for(int i = 1;i < pq.length;i++)
        {
            temp[i] = pq[i];
        }
        pq = temp;
    }
}

然后堆排序实现就很简单啦,将一个数组全部加入大顶堆,一个个拿出来就是已经排好序的啦,当然可以修改一下这个大顶堆的代码,让他更适合实现堆排序。
堆排序的时间复杂度是nlogn。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值