堆的概念与运用

1.堆是由一棵完全二叉树构成,如下图所示:

 大根堆就是头结点是堆的最大值,每一个子树头结点的值也算是其最大值。

小根堆是头结点是堆的最小值,每一个子树头结点的值也算是其最小值。

构造一个大根堆或者的方法就是子与父比较,若比父大则上浮取代父的位置,若比父小,则停在这个位置。小根堆类似。

大根堆的插入代码如下:

public static void swap(int arr[],int i,int j){
        int tem=arr[i];
        arr[i]=arr[j];
        arr[j]=tem;
    }
    //大根堆的构造(上浮操作)
   public static void heapInsert(int[] arr,int index){
       while(arr[index]>arr[(index-1)/2]){
           swap(arr,index,(index-1)/2);
           index=(index-1)/2;
       }
   }

取出一个大根堆中最大的数字:

将数字取出,然后将最后一个数移到第一个位置,然后那个位置的数进行下沉操作。与子节点比较大小,若比子节点小,则与其交换位置。

下沉的代码如下:

//下沉操作
   public static void heapify(int[] arr,int index,int heapSize){
        int left=index*2+1; //左孩子的下标
        while(left<heapSize){// 下方是否还有孩子
            int largest = left+1<heapSize && arr[left+1]>arr[left]
                    ?left+1:left; //判断哪个孩子大,把大的下标给largest
            //比较父亲和大孩子哪个更大
            largest = arr[largest]>arr[index]?largest:index;
            if(largest==index){
                break; //父亲比孩子大
            }
            swap(arr,largest,index);
            left=index*2+1;
        }
   }

2.堆排序:

将堆顶的值与堆末尾的值交换,堆的大小减一,然后此时堆顶元素下渗。直到最后堆的容量减到0为止。

public static void heapSort(int[] arr){
        if(arr==null || arr.length<2){
            return;
        }
        for (int i = 0; i < arr.length; i++) {
            heapInsert(arr,i);
        }
        int heapSize = arr.length;
        swap(arr,0,--heapSize);
        while(heapSize>0){
            heapify(arr,0,heapSize);
            swap(arr,0,--heapSize);
        }
    }

时间复杂度O(logN)。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值