优先队列

优先队列


优先队列实现以下功能:(大根堆)

  1. insert方法.(插入一个元素)``
  2. delete方法(删除指定元素)
    通过map查找元素在数组中对应的下标删除指定元素,另外使用数组最后一个元素代替这个位置上的元素.
  3. pop方法(删除最大元素(出队))
    array[0]删除
  4. get方法(获取最大元素)
    return array[0]
  5. increase方法(增加或减少某个元素的值)
    增加可以通过向上过滤完成,减少可以同向下过滤完成
  6. minVal方法(获取最小元素)

数据结构

//记录数据的数量
	private int size;
	//记录最小值
	private T min;
	//存储数据
	private T[] array;
	//存储对象与其在数组中位置的映射(索引)
	private HashMap<T,Integer> indexmap;

流程图

在这里插入图片描述
在这里插入图片描述

实现

接口
/**
 * 优先队列
 */
public interface BaseHeap <T extends HeapObject> {
    public void insert(T t) throws NullPointerException;
    public void insert(T[] t) throws NullPointerException;
    //获取最大元素
    public T get();
//最大元素出队
public T pop();
//删除指定元素
public T delete(T t)  throws NoSuchObjectException;
//获取最小元素
    public T minVal();
    //增加或减少元素值
    public void increase(T t,int val) throws NoSuchObjectException;
    public int size();
}
存储对象
public class HeapObject implements Comparable {
    private int data;
    private String key;
    public HeapObject(){}
    public HeapObject(int data,String key){
        this.data = data;
        this.key = key;
    }
public void add(int data){
    	this.data = this.data+data;
    }

    @Override
    public int compareTo(Object o) {
        return data-((HeapObject)o).data;
    }
    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public String getOnlykey() {
        return key;
    }

    public void setOnlykey(String key) {
        this.key = key;
    }
}
实现类

insert、delete、increase、update、pop可能会导致最小值改变,需要加条件加以判断更新
upPercolate、downPercolate会导致元素索引的变化,在过滤过程中也要更新indexmap中对应元素的索引

import java.rmi.NoSuchObjectException;
import java.util.HashMap;
//优先队列
public class BinaryHeap  <T extends HeapObject> implements BaseHeap<T>{
    private static final int DEFAULTSIZE    =   10;
    private int size;
    private T min;
    private T[] array;
    //store index of object in array
    private HashMap<T,Integer> indexmap;

    public BinaryHeap(){
        this(DEFAULTSIZE);
    }
    public BinaryHeap(T[] ts){
        this(ts.length*2);
        this.size = ts.length;
        T min = ts[0];
        for(int i=0;i<ts.length;i++){
            array[i] = ts[i];
            //find min
            if(ts[i].compareTo(min)<0)
                min = ts[i];
        }
        for(int i=ts.length-1;i>=0;i--)
            downPercolate(i);
        //find min of index
        this.min = min;
    }
    private BinaryHeap(int size){
        array =(T[]) new HeapObject[size];
        indexmap = new HashMap<>(size,10);
        min = null;
        this.size = 0;
    }

    @Override
    public void insert(T t) throws NullPointerException{
        if(null == t)
            throw new NullPointerException("tar is null");
        int index;
        //resize
        if(this.size==array.length){
            T[] old = array;
            array = (T[])new HeapObject[old.length*2];
            //extend size of array
            System.arraycopy(old,0,array,0,old.length);
        }
       Integer exist = indexmap.get(t);
       if(exist==null){
            array[index = size++] = t;
            this.upPercolate(index);
        }else{
           //如果堆中已存在对象,更新对象
            updateVal(exist);
            //更新最小值
            min = min==t ?min: foreachfindmin() ;
            return;
        }
        //min of index
        if(min==null)
            min = array[0];
        if(min!=null && min!=t &&t.compareTo(min)<0)
            min = t;
    }
    @Override
    public void insert(T[] t) {
        for(int i=0;i<t.length;i++)
            insert(t[i]);
    }

    public T get() {
        if (array == null || size == 0)
            throw new NullPointerException("there is no record");
        return array[0];
    }
    @Override
    public T delete(T t) throws NoSuchObjectException{
        Integer index  = indexmap.get(t);
        if(index==null)
            throw new NoSuchObjectException("指定对象不存在");
        T tar = array[index];
        indexmap.remove(tar);
        if(size==1){
            min = null;
            array[--size] = null;
            return tar;
        }
        array[index] =  array[--size] ;
        updateVal(index);
        min = min == tar ? foreachfindmin() : min ;
        return tar;
    }
    //提升对象的优先级
    @Override
    public void increase(T t,int val) throws NoSuchObjectException{
       Integer index  = indexmap.get(t);
       if(index==null)
           throw new NoSuchObjectException("指定对象不存在");
       t.add(val);
       if (val>0){
           upPercolate(index);
           min =  t == min  ? foreachfindmin() : min;
       } else if(val<0){
           downPercolate(index);
           //1.降低min权值  2.降低任意对象权值.
           min = t.getData()<min.getData() ? t : min;
       }
       else
           ;

    }
    //更新对象权值,并平衡堆
    private void updateVal(int index){
        T tar = array[index];
        int re = tar.compareTo(array[(index-1)/2]);
        if(re>0)
            upPercolate(index);
        else
            downPercolate(index);

    }
    //遍历查找最小值
    private T foreachfindmin(){
        int begin = (size-2)/2 + 1;
        int end = size-1;
        T t = array[begin];
        for(int i=begin;i<=end;i++)
            if(array[i].compareTo(t)<0)
                t=array[i];
        return t;
    }
//出队
@Override
public T pop() {
    if(this.size==0)
        return null;
    T re = array[0];
    indexmap.remove(re);
    if(this.size==1){
        array[--size] = null;
        min = null;
    }else{
        array[0]=array[--size];
        min = size==0 ? null : min;
        downPercolate(0);
    }
    return re;
}

    @Override
    public int size() {
        return this.size;
    }

    @Override
    public T minVal() {
        return min;
    }
    //上浮,并更新map中对象索引
    private void upPercolate(int index){
        int hole = index;
        T t = array[index];
        while((hole-1)/2>0
                && t.compareTo(array[(hole-1)/2])>0){
            array[hole]  = array[(hole-1)/2];
            indexmap.put(array[hole],hole);
            hole = (hole-1)/2;
        }
        if(array[0].compareTo(t)<0){
            array[hole] = array[0];
            indexmap.put(array[hole],hole);
            array[hole=0] = t;
        }else {
            array[hole] = t;
        }
        indexmap.put(array[hole],hole);
    }
    //下沉,并更新map中的索引
    private void downPercolate(int index){
        int hole = index;
        int i;
        T temp = array[index];
        while((hole*2+1)<this.size){
            i = hole*2+1;
            if(i+1<this.size && array[i+1].compareTo(array[i])>0)
                i++;
            if(temp.compareTo(array[i])>0)
                break;
            array[hole] = array[i];
            indexmap.put(array[hole],hole);
            hole = i;
        }
        array[hole]  =  temp;
        indexmap.put(array[hole],hole);
    }
}
测试
 public static void main(String[] args) throws Exception{
    BaseHeap heap = new BinaryHeap();
    Map<String,HeapObject> map = new HashMap<>();
    HeapObject obj = null;
    for(int i=0;i<10;i++){
        obj =  new HeapObject(i,String.valueOf(i));
        map.put(String.valueOf(i),obj);
        heap.insert(obj);
    }
    System.out.println("最大值:"+heap.pop().getData());
    heap.increase(map.get(String.valueOf(0)),100);
    System.out.println("某元素增加100后最大值:"+heap.pop().getData());
    System.out.println("最小值:"+heap.minVal().getData());
    heap.increase(map.get(String.valueOf(8)),-100);
    System.out.println("某元素减少100后最小值:"+heap.minVal().getData());
    System.out.print("依次出队: ");
    while(heap.size()!=0)
        System.out.print(heap.pop().getData()+" ");


}

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值