數據結構--用堆實現優先隊列

一、優先隊列實現方法

    應想到使用二叉查找樹實現優先隊列(線性表的思想被否決了,接下來該想到的也應該是樹結構了吧),​它可以使這兩種操作的平均運行時間都是O(logN)。但是使用二叉查找樹會存在兩個問題

1:根節點的選擇。

2:使用指針的必要性。(我們不需要那麼“精確”的排序)

所以我們使用一種名爲“二叉堆”的工具,它具有二叉查找樹的部分思想,但我們將用數組去實現它(你也可以認爲就是用數組實現了個二叉查找樹

二、實現heap類
public class Heap<E extends Comparable<E>> {
    private ArrayList<E> list = new ArrayList<>();

    public Heap(){}
    public Heap(E[] objects){
        for (E object:objects) {
            add(object);
        }
    }

    public void add(E newObject){
        list.add(newObject);
        int currentIndex = list.size()-1;

        while (currentIndex>0){
            int parentIndex = (currentIndex-1)/2;
            if(list.get(currentIndex).compareTo(list.get(parentIndex)) > 0){
                E temp = list.get(currentIndex);
                list.set(currentIndex, list.get(parentIndex));
                list.set(parentIndex, temp);
            }
            else
                break;
            currentIndex = parentIndex;
        }
    }

    public E remove(){
        if(list.size() == 0) return null;

        E removedObject = list.get(0);
        list.set(0, list.get(list.size()-1));
        list.remove(list.size()-1);

        int currentIndex = 0;
        while (currentIndex<list.size()){
            int rightChildIndex = currentIndex*2+2;
            int leftChildIndex = currentIndex*2+1;
            if (leftChildIndex >= list.size()) break;

            int maxIndex = leftChildIndex;
            if(rightChildIndex < list.size()){
                if(list.get(maxIndex).compareTo(list.get(rightChildIndex)) < 0){
                    maxIndex = rightChildIndex;
                }
            }
            if(list.get(currentIndex).compareTo(list.get(maxIndex)) < 0){
                E temp = list.get(maxIndex);
                list.set(maxIndex, list.get(currentIndex));
                list.set(currentIndex, temp);
                currentIndex = maxIndex;
            }
            else break;
        }
        return removedObject;
    }

    public int getSize(){
        return list.size();
    }
}

二、實現PriorityQueue類

public class MyPriorityQueue<E extends Comparable<E>> {
    private Heap<E> heap = new Heap<>();

    public void enqueue(E newObject){
        heap.add(newObject);
    }
    public E dequeue(){
       return heap.remove();
    }
    public int getSize() {
        return heap.getSize();
    }
}

三、實現測試類

public class TestPriorityQueue {
    public static void main(String[] args){
        Patient p1 = new Patient("Tom", 1);
        Patient p2 = new Patient("Jack", 8);
        Patient p3 = new Patient("Smith", 3);
        Patient p4 = new Patient("John", 5);

        MyPriorityQueue priorityQueue = new MyPriorityQueue();
        priorityQueue.enqueue(p1);
        priorityQueue.enqueue(p2);
        priorityQueue.enqueue(p3);
        priorityQueue.enqueue(p4);
        while (priorityQueue.getSize() > 0){
            System.out.println(priorityQueue.dequeue());
        }
    }
    static class Patient implements Comparable<Patient>{
        private String name;
        private int priority;

        public Patient(String name, int priority){
            this.name = name;
            this.priority = priority;
        }

        @Override
        public int compareTo(Patient o) {
            return o.priority - this.priority;
        }

        @Override
        public String toString() {
            return "Patient{" +
                    "name='" + name + '\'' +
                    ", priority=" + priority +
                    '}';
        }
    }
}

四、總結

       父結點:(i-1)/2

       左子節點:2 * i +1

       右子節點:2 * i +2

       實現Comparable<E>接口再重寫compareTo方法可以自定義比較器

 static class Patient implements Comparable<Patient>
@Override
        public int compareTo(Patient o) {
            return o.priority - this.priority;
        }

發佈了14 篇原創文章 · 獲贊 4 · 訪問量 9955
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章