优先队列

一个很简单的数据结构,但上午我还写错了,写这篇文章只是为了整理一下思路。参考:《算法导论》,《挑战程序设计》

什么是优先队列

百度百科

队列是一种特殊的线性表, 特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表。进行插入操作的端称为队尾,进行删除操作的端称为队头。

个人解释

通俗来讲就是一堆数列,比如1 2 3 4 5。有两个针对这堆数的操作
1:删除并返回队首的元素,常写作int pop()函数。
2:从队尾加入元素,常写作void push(int x)函数。
这样子的话,先入队的元素,就会先出队。与先入后出的栈相反。

优先队列

在队列的基础上,每次执行pop操作的时候,返回队列中最小或者最大的数。既然这样,那执行push操作的时候,也需要有相应的改变,不是单纯的往队尾加入元素了。

二叉堆

就是一棵完全二叉树,但是每个父亲节点的值都要比两个子节点的值要大或者小。
构建堆的时候,用的是一个足够大的数组,0下标表示根节点。假设某个节点的下标为i,则它的左儿子下标为i * 2 + 1,右儿子的下标为i * 2 + 2

实现

优先队列的实现,就是构造一个二叉堆

  1. 执行push操作的时候,在树的底层加入一个节点,然后通过该子节点和父亲节点的对比交换,将它放到适当的位置,使得它比父亲节点小,比子节点大。
  2. 执行pop操作的时候,返回树根部的元素,然后将最末端的节点提到根部,并向下插入,放到合适的位置。
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <ctime>
#define maxn 1000
using namespace std;

class priority_queque{
private:
    int a[maxn];
    int sz = 0;
    int id;
    int pre;
public:
    void push(int x){
        //自己的编号
        int i = sz++;
        while (i > 0){
            //父亲节点的编号
            int p = (i - 1) / 2;
            if (a[p] <= x) break;//如果父亲节点已经小于自己了,那就可以退出了
            a[i] = a[p];
            i = p;
        }
        a[i] = x;
    }
    int pop(){
        //最小值
        int t = a[0];
        //要提到根上的值
        int x = a[--sz];
        //从根开始向下交换
        int i = 0;
        while (i * 2 + 1 < sz){
            //比较儿子的值
            int l = i * 2 + 1;
            int r = i * 2 + 2;
            //令l变成最小儿子的编号
            if (r < sz && a[r] < a[l]) l = r;
            if (a[l] >= x) break;
            a[i] = a[l];
            i = l;
        }
        a[i] = x;
        return t;
    }
    void print(){
        for (int i = 0; i < sz; i++){
            cout << a[i] << " ";
        }
        cout << endl;
    }
};
int main(){
    srand((unsigned)time(NULL));
    priority_queque a;
    for (int i = 5; i >= 1; i--){
        int x = rand()% 100;
        printf("%d\n", x);
        a.push(x);
    }
    a.print();
    for (int i = 0; i < 5; i++){
        printf("%d, ", a.pop());
    }
}
    原文作者:Andywu_0010
    原文地址: https://www.jianshu.com/p/e9a10e5ba0ad
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞