将一个数组转化成最大堆的方法实现

本片是对上一篇的补充,实现的是一个小方法,就是将用户传来的数组变成堆,其实有一种比较简单的方法,就是将数组的元素进行遍历,然后将其一个一个加入到堆当中,但此做法时间复杂度为O(nlogn),相对于第二种做法时间比较长,第二中做法叫做heapify,时间复杂度为O(n),实现的思路还是挺容易的,就是先将用户传来的数组转换成动态数组,因为我的最大堆底层用的是自定义的动态数组类,然后此时,数组中的元素排列并不符合堆的特点,所以我们要重新对数组进行堆化,也就是将节点进行下沉(siftdown)操作<上篇博文有详细介绍>,首先,我们需要抛弃所有叶子节点(直接从其父节点开始,节省时间),所以,先找到最后一个节点的父节点,从它开始进行节点下沉操作,直到结束。该方法不难。

首先是Array类中,写一个构造方法,参数为数组

//传一个数组,将其转换成动态数组
    public Array(E arr[]) {
        data=(E[]) (new Object[arr.length]);
        for(int i=0;i<arr.length;i++) {
            data[i]=arr[i];          
        }
        size=arr.length;//注意,这里需要维护一下size!!
    }

然后是MaxHeap类中添加构造方法,此方法也是关键的实现数组转换成堆的关键

public MaxHeap(E arr[]) {
        array=new Array<>(arr);

//直接从尾节点的父亲节点开始遍历
        for(int i=parent(array.getSize()-1);i>=0;i--) {
            siftdown(i);//该方法的详情参考上一篇堆排序的博文
        }
    }

//接着,我们来看一下测试类,首先定义一个testHeap方法,该方法主要是为了测试直接遍历数组元素添加到堆的方法与heapify方法的性能差异,所以需要传两个参数,第一个是需要测试的数据,也就是testData,然后是一个boolean型的变量,用以表示是否需要使用heapify方法进行转换。

import java.util.Random;

public class test {
    private static double testHeap(Integer[] testData,boolean isHeapify) {
        long time=System.nanoTime();
        MaxHeap<Integer> heap=null;
        if(isHeapify) {
            heap=new MaxHeap<Integer>(testData);
        }
        else {

//如果用户传来的是false,就使用上文所说的第一种方法进行转换
            heap=new MaxHeap<Integer>();
            for (Integer num : testData) {
                heap.add(num);
            }
        }

//以下部分是为了测试堆的添加是否有错误
        int[] arr = new int[testData.length];
        for(int i = 0 ; i < testData.length ; i ++)
            arr[i] = heap.extractMax();

        for(int i = 1 ; i < testData.length ; i ++)
            if(arr[i-1] < arr[i])
                throw new IllegalArgumentException("Error");
        System.out.println("Test MaxHeap completed.");
        long time2=System.nanoTime();
        return (time2-time)/1000000000.0;
        
    }
    public static void main(String[] args) {
        int n=10000;
        Integer[] arr=new Integer[n];
        for(int i=0;i<arr.length;i++) {
            arr[i]=new Random().nextInt(Integer.MAX_VALUE);
        }
        double time1=testHeap(arr,false);
        System.out.println("直接添加"+time1);
        double time2=testHeap(arr,true);
        System.out.println("堆化添加"+time2);        

    }

}

测试结果如下

可以看到,heapify的方法相对于直接添加还是比较快的。

  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值