二叉堆的基本概念与实现

来源:互联网 发布:ubuntu修改用户名 编辑:程序博客网 时间:2024/06/17 17:15

基本概念

二叉堆又名堆,或者优先队列。一般实现在堆顶的元素总是最小的。
二叉堆是一颗用数组实现的完全二叉树。
要实现二叉堆必须满足以下条件:
1堆有序,二叉树中每一个子树的父节点不大于(大根堆)两个子节点。
2树的父节点的两个子节点位置为 2k和2k+1(不使用数组的0号索引),如果使用0号索引,两个子节点的位置为2*k+1和2*k=2。
要实现堆有序,主要依靠上浮(swim)和下沉(snik)两个操作。
在入队时,将数据插入到元素序列尾部,然后将元素上浮到应有的位置。
在出队时,将堆顶最小的元素删除,用元素序列尾部的元素交换到堆顶,然后进行下沉操作,恢复堆有序。

实现

/** * 二叉堆,小堆,降序 * @author yuli * */public class BinaryHeap<T extends Comparable<T>>{    private Comparable<T>[] data;    private int size;    private static final int DEFAULT_CAPACITY = 10;     public BinaryHeap() {        clean();    }    public void clean(){        size = 0;        swap(DEFAULT_CAPACITY);    }    /**     * 添加元素,并将元素上浮     * @param t     */    public void insert(T t){        if(size+1 >= data.length){            swap(2*size +1);        }        //0号位置要空着,所以+了再放元素        data[++size] = t;        swim(size);    }    /**     * 删除元素,并恢复堆有序     * @return     */    public Comparable<T> delete(){        if(size < 0){            System.out.println("没元素啦");            return null;        }        //获得堆顶元素        Comparable<T> t = data[1];        //将堆顶元素替换成堆底元素        data[1] = data[size];        //移除堆底元素,顺便把容器的大小-1        data[size--] = null;        //将交换来的元素下沉到合适的位置,恢复堆的有序性        sink(1);        return t;     }    /**     * 上浮元素,如果父节点大于子节点,就上浮元素     * @param k 元素的索引     */    public void swim(int k){        //如果子元素不是头结点,并且父节点大于子节点就交换        while(k > 1 && less(data[k],data[k/2])){            exchange(data, k, k/2);            k = k/2;        }    }    private void exchange(Comparable<T>[] t,int v,int w){        Comparable<T> temp = t[v];        t[v] = t[w];        t[w] = temp;    }    /**     * 下沉元素,如果元素的子节点大于父节点,就下沉元素     * @param k 元素的索引     */    public void sink(int k){        while(2*k <= size ){            //获取子节点            int j = 2*k;            //从两个孩子中选出较小那个            if(j+1 <= size && !less(data[j],data[j+1])){                j++;            }            //如果子节点不小于父节点就不交换            if(less(data[k],data[j])){                break;            }            exchange(data, k, j);            k = j;        }    }    /**     * v是否比w小     * @param v     * @param w     * @return     */    public boolean less (Comparable v,Comparable w){        return v.compareTo(w) < 0 ;    }    /**     * 扩容,交换元素     * @param newSize     */    @SuppressWarnings("unchecked")    public void swap(int newSize){        if(newSize < size){            return;        }        Comparable<T>[] newItems = new Comparable[newSize];        for(int i=0;i<this.size;i++){            newItems[i+1]=data[i+1];        }        this.data = newItems;    }}
原创粉丝点击