优先级队列和堆之间的区别

新手上路,请多包涵

似乎优先级队列只是一个具有正常队列操作(如插入、删除、顶部等)的堆。这是解释优先级队列的正确方法吗?我知道您可以以不同的方式构建优先级队列,但是如果我要从堆构建优先级队列,是否有必要创建一个优先级队列类并提供构建堆和队列操作的说明,或者真的不需要构建班上?

我的意思是,如果我有一个构建堆的函数和执行插入和删除等操作的函数,我是否需要将所有这些函数放在一个类中,或者我可以通过在 main 中调用它们来使用指令吗? --- .

我想我的问题是拥有一组函数是否等同于将它们存储在某个类中并通过一个类使用它们或仅使用函数本身。

下面是优先级队列实现的所有方法。这足以将其称为实现还是我需要将其放入指定的优先级队列类中?

 #ifndef MAX_PRIORITYQ_H
#define MAX_PRIORITYQ_H
#include <iostream>
#include <deque>
#include "print.h"
#include "random.h"

int parent(int i)
{
    return (i - 1) / 2;
}

int left(int i)
{
    if(i == 0)
        return 1;
    else
        return 2*i;
}

int right(int i)
{
    if(i == 0)
        return 2;
    else
        return 2*i + 1;
}

void max_heapify(std::deque<int> &A, int i, int heapsize)
{
    int largest;
    int l = left(i);
    int r = right(i);
    if(l <= heapsize && A[l] > A[i])
        largest = l;
    else
        largest = i;
    if(r <= heapsize && A[r] > A[largest])
        largest = r;
    if(largest != i) {
        exchange(A, i, largest);
        max_heapify(A, largest, heapsize);
        //int j = max_heapify(A, largest, heapsize);
        //return j;
    }
    //return i;
}

void build_max_heap(std::deque<int> &A)
{
    int heapsize = A.size() - 1;
    for(int i = (A.size() - 1) / 2; i >= 0; i--)
        max_heapify(A, i, heapsize);
}

int heap_maximum(std::deque<int> &A)
{
    return A[0];
}

int heap_extract_max(std::deque<int> &A, int heapsize)
{
    if(heapsize < 0)
        throw std::out_of_range("heap underflow");
    int max = A.front();
    //std::cout << "heapsize : " << heapsize << std::endl;
    A[0] = A[--heapsize];
    A.pop_back();
    max_heapify(A, 0, heapsize);
    //int i = max_heapify(A, 0, heapsize);
    //A.erase(A.begin() + i);
    return max;
}

void heap_increase_key(std::deque<int> &A, int i, int key)
{
    if(key < A[i])
        std::cerr << "New key is smaller than current key" << std::endl;
    else {
        A[i] = key;
        while(i > 1 && A[parent(i)] < A[i]) {
            exchange(A, i, parent(i));
            i = parent(i);
        }
    }
}

void max_heap_insert(std::deque<int> &A, int key)
{
    int heapsize =  A.size();
    A[heapsize] = std::numeric_limits<int>::min();
    heap_increase_key(A, heapsize, key);
}

原文由 Mars 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 353
2 个回答

拥有一个具有您需要的接口的类(只需插入和 pop-max?)有其优势。

  • 您可以稍后交换实现(例如,列表而不是堆)。
  • 阅读 使用 队列的代码的人不需要理解堆数据结构的更困难的接口。

我想我的问题是拥有一组函数是否等同于将它们存储在某个类中并通过一个类使用它们或仅使用函数本身。

如果您只是从“我的程序如何表现”的角度来思考,它基本上是等价的。但就“人类读者理解我的程序有多容易”而言,它并不等同

原文由 Sebastian 发布,翻译遵循 CC BY-SA 4.0 许可协议

优先级队列是一种 抽象数据类型。它是描述特定接口和行为的简写方式,并没有说明底层实现。

堆是一种 数据结构。它是一种存储数据的特定方式的名称,它使某些操作非常有效。

碰巧堆是实现优先级队列的一个非常好的数据结构,因为堆数据结构高效的操作是优先级队列接口需要的操作。

原文由 Benjamin Lindley 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题