算法之最简单的堆笔记

公共函数:

比较大小:

private boolean less(Array pq, int i ,int j){
    return pq[i].compareTo(pq[j]) < 0 ;
}

交换:

private void exch(Array pq , int i , int j ){
    Key t = pq[i] ; 
    pq[i] = pq[j] ;
    pq[j] = t ;
}

上浮: 当儿大于父,将儿不断向上交换。初始化时一般从N/2位置开始

private void swim(Array pq ,int k){
    while( k>1 && less( k/2, k)){
        exch(pq , k/2 , k);
    }
}


下沉: 当父小于儿,将父不断向下。初始化时一般从1开始

private void sink(Array pq , int k){
    while (2*k <= N){        //N是pq.length
        int j = 2*k;
        if(j < N && less(j , j+1)) j++;
        if(!less(pq , k , j)) break;
        exch(pq , k , j);
        k = j;
    }
}


如图:



概念:

每个节点都大于其子节点,这是堆的特性。所以当初始堆不符合这样的特点时候,就需要进行堆的初始化。



堆的初始化:

1)堆初始化主要是满足每个父节点大于等于子节点,而叶节点根本没有子节点,所以不考虑叶节点

2)因为不需要考虑叶节点,所以N/2位置一般为截断点

3)遇到不符合特点的节点,通过sink或者swim函数来调整

public void init(){          
    int N = a.length;
    for(int k = 1;k <= N/2;k++){
        sink(a , k)
    }
}



堆的添加:

1)把新增的节点放到最后

2)节点上浮到相应位置即可

public void insert (Array pq , Key v) {
    int N = pq.length;    
    pq[++N] = v;
    swim(pq , N);
}


堆的删除:

1)把要删除的元素与最后叶节点交换位置

2)被交换的叶节点进行下沉操作

3)把要删除的元素为null

public void del(int d , Array pq){
    Key del = pq[d];        
    int N = pq.length;
    exch(pq , d , N--); // 交换最后叶节点与要删除元素位置
    sink(pq , d);       //下沉操作
    pq[N+1] = null;     //要删除元素置null
}


堆的排序:

1)根节点与叶节点互换

2)下沉操作

3)原根节点删除并存入新数组中

4)重复上面操作

while (N > 1) {
    exch(pq , 1 ,N--) ;    // 交换根和最大叶节点位置
    sink(pq , 1);          // 现在根节点下沉操作
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值