1. 程式人生 > 實用技巧 >自定義索引優先佇列

自定義索引優先佇列

/**
 * @desc: 自定義索引優先佇列,可修改,刪除索引對應的值
 * @author: 毛會懂
 * @create: 2021-01-06 17:20:00
 **/
public class MyIndexPriorityQueue<T extends Comparable<T>> {
    private T[] arr;//儲存陣列元素
    private int[] pq;//儲存元素的下標,符合堆結構
    private int[] qp;//儲存元素下標的堆的反序,pq陣列中的值作為索引,pq陣列的索引作為值j
    private int size;

    
public MyIndexPriorityQueue(Integer size){ arr = (T[])new Comparable[size]; pq = new int[size + 1]; qp = new int[size + 1]; for (int i = 0; i < qp.length; i++) { //預設情況下,qp逆序中不儲存任何索引 qp[i] = -1; } this.size = 0; } //佇列大小 public
Integer getSize(){ return size; } //是否為空 public Boolean isEmpty(){ return size == 0; } //某一個位置是否有元素 public Boolean contains(int k){ return qp[k] != -1; } //指定位置,新增元素 public void add(int i,T t){ arr[i] = t; size++; //元素的下標需要符合堆結構
pq[size] = i; qp[i] = size; swim(size); } //刪除最大元素 public T delMax(){ if(size <= 0){ return null; } T t = arr[pq[1]]; change(1,size); size--; sink(1); return t; } //修改某一個位置的元素 public void update(int k ,T t){ if(!contains(k)){ return; } //修改元素值 arr[k] = t; //找到此元素在pq的下標 int index = qp[k]; //上浮 swim(index); //下沉 sink(index); } //刪除某一個位置元素 public void delete(int k){ if(!contains(k)){ return; } //刪除元素 arr[k] = null; //交換位置 int index = qp[k]; change(index,size); //刪除下標 qp[pq[size]] = -1; pq[size] = -1; size--; //上浮 swim(index); //下沉 sink(index); } //最小元素關聯的索引 public int getMinIndex(){ if(size >=1) { return pq[1]; } return -1; } //上浮 private void swim(int k){ while (k > 1){ if(great(k,k/2)){ change(k,k/2); } k = k /2; } } //下沉 private void sink(int k){ while (2 * k < size){ int max; if(2 * k + 1 <= size) { if (great(2 * k, 2 * k + 1)) { max = 2 * k; } else { max = 2 * k + 1; } }else{ max = 2 * k; } if(great(max,k)){ change(max,k); } k = max; } } private Boolean great(int i,int j){ return arr[pq[i]].compareTo(arr[pq[j]]) > 0; } private void change(int i,int j){ int temp = pq[i]; pq[i] = pq[j]; pq[j] = temp; qp[pq[i]] = i; qp[pq[j]] = j; } }

測試程式碼:

//索引優先佇列
public static void main(String[] args) {
MyIndexPriorityQueue queue = new MyIndexPriorityQueue(20);
queue.add(0,"A");
queue.add(2,"H");
queue.add(1,"D");
queue.add(3,"O");
queue.add(4,"E");
queue.add(5,"W");
queue.add(6,"G");
queue.add(7,"T");


System.out.println("最大的元素所在的索引:"+queue.getMinIndex());
System.out.println("修改元素");
queue.update(6,"Z");
System.out.println("刪除元素");
queue.delete(2);
for(int i = 0;i < 8;i++){
System.out.print(queue.delMax() + ", ");
}
System.out.println("over");
}