使用堆的优先级队列

时间:2017-09-02 17:40:45

标签: c++ c++11 heap priority-queue

我从算法简介学习后编写了这段代码。我无法找出代码有什么问题。我已经为heapsort编写了代码并且运行良好。 heap_extract_max()将返回最大值。 heap_increase_key()增加元素的优先级。 Here我使用单链表编写优先级队列程序,运行良好。

#include <iostream>
#include <vector>
#include <algorithm>

template<typename T>
void max_heapify(std::vector<T>& array, size_t index)
{
  size_t largest;
  size_t left  = (2*index) + 1;
  size_t right = left + 1;

  if(left < array.size() && array[left] > array[index])
    largest = left;
  else
    largest = index;

  if(right < array.size() && array[right] > array[largest])
    largest = right;

  if(largest != index)
  {
    int tmp = array[index];
    array[index] = array[largest];
    array[largest] = tmp;
    max_heapify(array, largest);
  }
}

template<typename T>
void build_max_heap(std::vector<T>& array)
{
  for(size_t i = (array.size()/2) - 1; i >= 0; i--)
  max_heapify(array, i);
}

template<typename T>
T heap_maximum(std::vector<T>& array)
{
  return array[0];
}

template<typename T>
T heap_extract_max(std::vector<T>& array)
{
  if(array.size() < 0)
  {
    std::cerr << "Heap Underflow \n";
  }
  else
  {
    T max = array[0];
    array[0] = array[array.size() - 1];
    //array.size() = array.size() - 1;
    max_heapify(array, 1);
    return max;
  }
}

template<typename T>
void heap_increase_key(std::vector<T>& array, size_t index, T value)
{
  if(value < array[index])
  {
    std::cerr <<"New value is smaller than the current value\n";
    return;
  }
  else
  {
    array[index] = value;
    while(index > 0 && array[(index/2) - 1] < array[index])
    {
      std::swap(array[index], array[(index/2) - 1]);
      index = (index/2) - 1;
    }
  }
}

template<typename T>
void max_heap_insert(std::vector<T>& array, T value)
{
  array[array.size()] = -1;
  heap_increase_key(array, array.size(), value);
}

int main()
{
std::vector<int> v({1, 2, 6, 3, 7});
build_max_heap(v);
std::cout << heap_extract_max(v)<<"\n";
for(size_t i = 0; i < v.size(); i++)
{
  std::cout << v[i] << " ";
}
std::cout << "\n";
}

没有显示任何输出。我在写命令

$ g++ -std=c++11 priorityqueue.cpp -o priorityqueue
$ ./priorityqueue

2 个答案:

答案 0 :(得分:2)

问题在于以下功能如果是这样的话会返回什么 因为那个

  

控制可能会达到无效功能的结束

template<typename T>
T heap_extract_max(std::vector<T>& array)
{
    if(array.size() < 0)
    {
        std::cerr << "Heap Underflow \n";
    }
    else
    {
        T max = array[0];
        array[0] = array[array.size() - 1];
        //array.size() = array.size() - 1;
        max_heapify(array, 1);
        return max;
    }
}

为if case

添加return -1或其他任何内容
if(array.size() < 0)
{
    std::cerr << "Heap Underflow \n";
    return -1;
}

第二个问题

for(size_t i = (array.size()/2) - 1; i >= 0; i--)
  

无符号表达式的比较&gt; = 0始终为真

尝试改为:(按照Serge Rogatch的建议)

for(int64_t i = (int64_t(array.size())/2) - 1; i >= 0; i--)

提取它也有问题 在更改结果之前

7
2 3 6 1 2 
Program ended with exit code: 0

由于错误处理remove .Handled已在下面的代码中正确删除

template<typename T>
T heap_extract_max(std::vector<T>& array)
{
    if(array.size() < 0)
    {
        std::cerr << "Heap Underflow \n";
        return -1;
    }
    else
    {
        T max = array[0];
        array[0] = array[array.size() - 1];
        array.erase(std::remove(array.begin(), array.end(), array[0]),
                   array.end());
        array.shrink_to_fit();
        max_heapify(array, 0);
        return max;
    }
}

更改后

7
6 3 1 2 
Program ended with exit code: 0

答案 1 :(得分:1)

您的程序似乎进入无限循环或崩溃。我在这里看到一个问题:

for(size_t i = (array.size()/2) - 1; i >= 0; i--)

由于i是无符号的,因此始终为i >= 0。另外,对于array.size() <= 1,您使用一些大的正整数对其进行初始化,因为i尝试为负数,但size_t从不为负数,因此数字会包含。

尝试更改为:

for(int64_t i = (int64_t(array.size())/2) - 1; i >= 0; i--)

此外,您似乎混淆了基于0 - 和1的数组索引,您应该array.pop_back()代替//array.size() = array.size() - 1;。此外,您似乎打算array[1]而不是array[0]

T max = array[0];
array[0] = array[array.size() - 1];

如果坚持使用基于1的索引,则应在数组中的索引0放置并保留一个虚拟元素:

std::vector<int> v({/*dummy*/-1, 1, 2, 6, 3, 7});

数组大小永远不会消极,因此您不需要if(array.size() < 0)以及then子句中的内容。

尽管基于0的索引在C ++中更自然,并且堆也可以用它来实现。为此,您需要修改所有索引算法,如:

size_t left  = (2*index) + 1;
size_t right = left + 1;

array[(index/2) - 1]