创建堆以及实现堆排序

什么是堆???
可以把堆看成是一颗完全二叉树,并且这颗完全二叉树有一个特点:根节点比其左右叶子结点的值都大或者都小。如果每一个根节点比其左右叶子节点的值都大,则称之为大顶堆,反之就称为小顶堆。这一规则必须在完全二叉树的任一子树都满足。
完全二叉树的特点:设根节点的索引值为index;
(1)左节点的索引值为 2indexe +1;
(2)右节点的索引值为 2
index+2;
(3)其父节点的值为(index-1)/2;
//构造小顶堆

public static void minHeap(int[] data,int size,int index)
{
    //左子节点
    int leftNode = 2*index+1;
    //右子节点
    int rightNode = 2*index+2;
    int max = index;
    //和两个子节点分别对比,找出最大的节点
    if(leftNode < size&&data[leftNode] <data[max])
    {
        max = leftNode;
    }
    if(rightNode< size&&data[rightNode] < data[max])
    {
        max = rightNode;
    }
    //交换位置
    if(max!=index)
    {
        int temp = data[index];
        data[index] = data[max];
        data[max] = temp;
        //递归进行该节点子树小顶堆的创建
        minHeap(data,size,max);
    }
}
//构造完全的小顶堆

public static void BuildminHeap(int[] data)
{
    int start = (data.length-1)/2;
    for(int i = start; i >=0;i--)
    {
        minHeap(data,data.length,i);
    }
}
//进行小顶堆排序
public static void minHeapSort(int[] data)
{
    for(int i = data.length-1; i>0;i--)
    {
        int temp = data[0];
        data[0] = data[i];
        data[i] = temp;
        minHeap(data, i, 0);
    }
}

//构造大顶堆

public static void maxHeap(int[] data,int size,int index)
{
    //左子节点
    int leftNode = 2*index+1;
    //右子节点
    int rightNode = 2*index+2;
    int max = index;
    //和两个子节点分别对比,找出最大的节点
    if(leftNode < size&&data[leftNode] >data[max])
    {
        max = leftNode;
    }
    if(rightNode< size&&data[rightNode] > data[max])
    {
        max = rightNode;
    }
    //交换位置
    if(max!=index)
    {
        int temp = data[index];
        data[index] = data[max];
        data[max] = temp;
        maxHeap(data,size,max);
    }
}
//构造完全的大顶堆
public static void BuileMaxHeap(int[] data)
{

    int start = (data.length-1)/2;
    for(int i = start; i >=0;i--)
    {
        maxHeap(data,data.length,i);
    }
}
//进行大顶堆排序
public static void maxHeapSort(int[] data)
{
    for(int i = data.length-1; i>0;i--)
    {
        int temp = data[0];
        data[0] = data[i];
        data[i] = temp;
        maxHeap(data, i, 0);
    }
}

利用以上的知识,实现从数以百万计的数据中获取最大的前10个数字或者任意数量的最大数字,经测试1000000个数字耗时4毫秒。思想就是:先创建存有一定数字的小顶堆,根据小顶堆的性质,最小的数字位于根节点,因此后面来的数字只需与根节点相比较,比根节点大就进行交换,然后重新构造小顶堆,比根节点小则继续向后寻找。

public static int[] GetMaxNumber(int count, int[] data)
{
    int[] maxNumber = new int[count];
    //先取10个数字放入data中
   for(int i =0; i < count; i++)
    {
        maxNumber[i] = data[i];
    }
   //构造小顶堆
    BuildminHeap(maxNumber);
   //获取data中count以后的数字,与maxNumber中的第一个元素进行比较,比第一个元素大就交换,重新构建小顶堆
    for(int j = count;j < data.length; j++)
    {
        if(data[j] > maxNumber[0])
        {
            maxNumber[0] = data[j];
            BuildminHeap(maxNumber);
        }
    }
    return maxNumber;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值