数据结构--用堆实现优先队列

一、优先队列实现方法

    应想到使用二叉查找树实现优先队列(线性表的思想被否决了,接下来该想到的也应该是树结构了吧),​它可以使这两种操作的平均运行时间都是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;
        }

猜你喜欢

转载自blog.csdn.net/qq_34198877/article/details/79686234