优先队列的简单实现方式

       很多情况下我们会收集一些元素,处理当前键值最大的元素,然后再收集更多的元素,再处理当前键值最大的元素,如此反复。这种情况下,一种合适的数据结构应该支持两种操作:删除最大元素和插入元素,这种数据类型叫做优先队列。

       一种基于堆得优先队列简单实现方式:

       

public class MaxPQ<Key extends Comparable<Key>> {
    private Key[] pq;
    private int N=0;
    public MaxPQ(int maxN){
        pq=(Key[])new Comparable[maxN+1];
    }

    public boolean isEmpty(){
        return N==0;
    }

    public int size(){
        return N;
    }

    public void insert(Key v){
        pq[++N]=v;
        swim(N);
    }

    public Key delMax(){
        Key max=pq[1];
        exch(1,N--);
        pq[N+1]=null;
        sink(1);
        StdOut.println("删除了"+max);
        return max;
    }

    private boolean less(int i,int j){
        return pq[i].compareTo(pq[j])<0;
    }

    private void exch(int i,int j){
        Key t=pq[i];
        pq[i]=pq[j];
        pq[j]=t;
    }

    private void sink(int k){
        while(2*k<=N){
            int j=2*k;
            if(j<N&&less(j,j+1))j++;
            if(!less(k,j))break;
            exch(k,j);
            k=j;
        }
    }

    private void swim(int k){
        while(k>1&&less(k/2,k)){
            exch(k/2,k);
            k=k/2;
        }
    }

    public static void main(String[] args){
        int M=5;
        MaxPQ<Transaction> pq=new MaxPQ<>(M+1);
        while(StdIn.hasNextLine()){
            pq.insert(new Transaction(StdIn.readLine()));

            if(pq.size()>M){
                pq.delMax();
            }
        }

        Stack<Transaction> stack=new Stack<Transaction>();
        while(!pq.isEmpty())stack.push(pq.delMax());
        for(Transaction t:stack) StdOut.println(t);
    }
}

       索引优先队列的实现方式:

public class IndexMinPQ<Key extends Comparable<Key>> {

    private int N;
    private int[] pq;
    private int[] qp;
    private Key[] keys;

    public IndexMinPQ(int maxN) {
        N = 0;
        pq = new int[maxN + 1];
        qp = new int[maxN + 1];
        keys = (Key[]) new Comparable[maxN + 1];
        for (int i = 0; i <= maxN; i++) qp[i] = -1;
    }

    public void insert(int k, Key key) {

        if (contains(k)) throw new RuntimeException("item is already in pq");
        N++;
        qp[k] = N;
        pq[N] = k;
        keys[k] = key;
        swim(N);
    }

    public void change(int k, Key key) {
        if (!contains(k)) throw new RuntimeException("item is not in pq");
        keys[k] = key;
        swim(qp[k]);
        sink(qp[k]);
    }

    public boolean contains(int k) {
        return qp[k] != -1;
    }

    public void delete(int i) {
        if (i < 0 || i >= N) throw new IndexOutOfBoundsException();
        if (!contains(i)) throw new RuntimeException("index is not in the priority queue");
        int index = qp[i];
        exch(index, N--);
        swim(index);
        sink(index);
        keys[i] = null;
        qp[i] = -1;
    }

    public int delMin() {
        if (N == 0) throw new RuntimeException("Priority queue underflow");
        int min = pq[1];
        exch(1, N--);
        sink(1);
        assert min == pq[N + 1];
        qp[min] = -1;
        keys[min] = null;
        pq[N + 1] = -1;
        return min;

    }

    public void swim(int k) {
        while (k > 1 && less(k / 2, k)) {
            exch(k / 2, k);
            k = k / 2;
        }
    }

    private void sink(int k) {
        while (2 * k <= N) {
            int j = 2 * k;
            if (j < N && less(j, j + 1)) j++;
            if (!less(k, j)) break;
            exch(k, j);
            k = j;
        }
    }

    public boolean less(int i, int j) {
        return keys[pq[i]].compareTo(keys[pq[j]]) > 0;
    }

    public void exch(int i, int j) {
        int swap = pq[i];
        pq[i] = pq[j];
        pq[j] = swap;
        qp[pq[i]] = i;
        qp[pq[j]] = j;

    }

    public boolean isEmpty() {
        return N == 0;
    }

    public int size() {
        return N;
    }


    public static void main(String[] args) {
        // insert a bunch of strings
        String[] strings = {"it", "was", "the", "best", "of", "times", "it", "was", "the", "worst"};

        IndexMinPQ<String> pq = new IndexMinPQ<String>(strings.length);
        for (int i = 0; i < strings.length; i++) {
            pq.insert(i, strings[i]);
        }

        // delete and print each key
        while (!pq.isEmpty()) {
            int i = pq.delMin();
            StdOut.println(i + " " + strings[i]);
        }
        StdOut.println();

        // reinsert the same strings
        for (int i = 0; i < strings.length; i++) {
            pq.insert(i, strings[i]);
        }

        while (!pq.isEmpty()) {
            pq.delMin();
        }
    }
}






  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
多机调度问题是一个经典的任务调度问题,可以使用优先队列实现。 首先,我们需要定义任务的数据结构,包括任务的ID、所需的执行时间以及优先级等信息。 然后,我们创建一个优先队列,每个任务按照优先级进行排序。可以使用最小堆来实现这个优先队列。 在任务到达时,将任务插入到优先队列中。每次从优先队列中选择优先级最高的任务进行调度,并执行任务。 下面是一个简单的示例代码: ```python import heapq class Task: def __init__(self, task_id, execution_time, priority): self.task_id = task_id self.execution_time = execution_time self.priority = priority # 定义任务的比较方式,按照优先级进行比较 def __lt__(self, other): return self.priority < other.priority class Scheduler: def __init__(self): self.task_queue = [] # 优先队列 def add_task(self, task): heapq.heappush(self.task_queue, task) def schedule(self): while len(self.task_queue) > 0: task = heapq.heappop(self.task_queue) print(f"Executing task {task.task_id} with priority {task.priority}") # 执行任务 for _ in range(task.execution_time): # 模拟任务执行 pass if __name__ == "__main__": scheduler = Scheduler() # 创建一些任务并添加到调度器中 task1 = Task(1, 5, 3) task2 = Task(2, 3, 2) task3 = Task(3, 7, 1) scheduler.add_task(task1) scheduler.add_task(task2) scheduler.add_task(task3) # 调度任务 scheduler.schedule() ``` 上述代码中,我们使用 `heapq` 库来实现最小堆,其中 `heappush` 和 `heappop` 分别用于向堆中插入元素和弹出优先级最高的元素。 在调度过程中,我们每次选择优先级最高的任务进行执行。可以根据实际需求来调整任务的优先级和执行时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值