C++作为二叉堆的优先级队列

发布于 2024-11-24 02:08:13 字数 4196 浏览 2 评论 0原文

一直在取得进展,但仍然无法弄清楚我的无限循环在哪里...

头文件:

#include <string>

class priority_queue_overflow{};    //if insert tries to exceed the size of A then throw priority_queue_overflow() 
class priority_queue_underflow{};   //if extract_min tries is called on an empty heap then throw priority_queue_overflow() 

class priority_queue {
private:

  class pair {
  public:
    std::string object;
    double key;
  };

  pair* A;  //the array used to store the heap
  int heapsize; //the current heap size
  int size; //the current size of the array: does not change

  void heapify(int k);  //as described in Cormen et al

public:

  priority_queue(int n); //don't forget to allocate the array of size n+1 as we don't use slot zero
  ~priority_queue();    //delete the array

  bool empty(); //true/false depending upon whether the heap is empty
  void insert(std::string s, double priority); //add s to the heap with the given priority as its key
  std::string extract_min();    //remove the string of lowest key and return that string

  operator std::string();
};

cpp 文件:

/**
 * implementing the priority queue as a binary heap
 *
 */

#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>
#include <map>
#include <algorithm>

#include "binary_heap.hpp"

/***********************
 *** inline functions
 ***********************/
inline int left(int i) { return  2*1; } // ( i << 1 )

inline int right(int i) { return 2*i+1; } // (i << 1 | 1)

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


/*********************
 *** constructor
 *********************/
priority_queue::priority_queue(int n)  //don't forget to allocate the array of size n+1 as we don't use slot zero 
  :heapsize(0), size(n)
{
  A = new pair[n+1];
}


/*********************
 *** destructor
 *********************/
priority_queue::~priority_queue()  //delete the array
{
  delete[] A; // iterrate through delete each elem
}


/*******************************************
 *** heapify * finds max of three things
 *******************************************/
void priority_queue::heapify(int k)
{
  std::cout<<"HERE HEAP"<<'\n';
  pair smallest = A[k];
  int pos = k;        

  //only treat child as object if it's inside heap
  if (left(k) <= heapsize and A[left(k)].key < A[pos].key) {

    // update variables
    smallest = A[left(k)];
    pos = left(k);
  }

  // identical for right
  if (right(k) <= heapsize and A[right(k)].key < A[pos].key) {

    // update variables
    smallest = A[right(k)];
    pos = right(k);
  }

  // after both if's exectued: smallest and pos contain smallest key

  // only need to do something if pos is !=i
  std::cout<< pos <<" == "<< k<<'\n';

  if (pos != k) {

    // swap items
    std::swap(A[k], A[pos]);

    // go recursive   
    heapify(pos);
  }
}


/****************
 *** empty
 ****************/
bool priority_queue::empty()
{
  return (heapsize == 0);
}


/****************
 *** insert
 ****************/
void priority_queue::insert(std::string s, double priority)  //add s to the heap with the given priority as its key
{
  if (heapsize == size) {
    throw priority_queue_overflow();
  }

  ++heapsize;  
  A[heapsize].object = s;
  A[heapsize].key = priority;

  int i(heapsize);
  while (i > 1 and A[parent(i)].key > A[i].key) {
    std::swap(A[parent(i)], A[i]);
    i = parent(i);  
  }
}


/*******************
 *** extract_min
 *******************/
std::string priority_queue::extract_min()  //remove the string of lowest key and return that string
{
  if (heapsize == 0) {
    throw priority_queue_underflow();
  }

  std::string ans = A[1].object;
  A[1] = A[heapsize];
  --heapsize;
  heapify(1);
  return ans;        
}


/**********************************
 *** function operator overload
 **********************************/
priority_queue::operator std::string()
{
  std::stringstream text; 
  int i(1);  

  while (i <= size) { 
    text << A[i].object << std::endl;
    ++i;
  } 
  return text.str(); 
}

have been making progress, but still can't figure out where my infinite loop is...

header file:

#include <string>

class priority_queue_overflow{};    //if insert tries to exceed the size of A then throw priority_queue_overflow() 
class priority_queue_underflow{};   //if extract_min tries is called on an empty heap then throw priority_queue_overflow() 

class priority_queue {
private:

  class pair {
  public:
    std::string object;
    double key;
  };

  pair* A;  //the array used to store the heap
  int heapsize; //the current heap size
  int size; //the current size of the array: does not change

  void heapify(int k);  //as described in Cormen et al

public:

  priority_queue(int n); //don't forget to allocate the array of size n+1 as we don't use slot zero
  ~priority_queue();    //delete the array

  bool empty(); //true/false depending upon whether the heap is empty
  void insert(std::string s, double priority); //add s to the heap with the given priority as its key
  std::string extract_min();    //remove the string of lowest key and return that string

  operator std::string();
};

cpp file:

/**
 * implementing the priority queue as a binary heap
 *
 */

#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>
#include <map>
#include <algorithm>

#include "binary_heap.hpp"

/***********************
 *** inline functions
 ***********************/
inline int left(int i) { return  2*1; } // ( i << 1 )

inline int right(int i) { return 2*i+1; } // (i << 1 | 1)

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


/*********************
 *** constructor
 *********************/
priority_queue::priority_queue(int n)  //don't forget to allocate the array of size n+1 as we don't use slot zero 
  :heapsize(0), size(n)
{
  A = new pair[n+1];
}


/*********************
 *** destructor
 *********************/
priority_queue::~priority_queue()  //delete the array
{
  delete[] A; // iterrate through delete each elem
}


/*******************************************
 *** heapify * finds max of three things
 *******************************************/
void priority_queue::heapify(int k)
{
  std::cout<<"HERE HEAP"<<'\n';
  pair smallest = A[k];
  int pos = k;        

  //only treat child as object if it's inside heap
  if (left(k) <= heapsize and A[left(k)].key < A[pos].key) {

    // update variables
    smallest = A[left(k)];
    pos = left(k);
  }

  // identical for right
  if (right(k) <= heapsize and A[right(k)].key < A[pos].key) {

    // update variables
    smallest = A[right(k)];
    pos = right(k);
  }

  // after both if's exectued: smallest and pos contain smallest key

  // only need to do something if pos is !=i
  std::cout<< pos <<" == "<< k<<'\n';

  if (pos != k) {

    // swap items
    std::swap(A[k], A[pos]);

    // go recursive   
    heapify(pos);
  }
}


/****************
 *** empty
 ****************/
bool priority_queue::empty()
{
  return (heapsize == 0);
}


/****************
 *** insert
 ****************/
void priority_queue::insert(std::string s, double priority)  //add s to the heap with the given priority as its key
{
  if (heapsize == size) {
    throw priority_queue_overflow();
  }

  ++heapsize;  
  A[heapsize].object = s;
  A[heapsize].key = priority;

  int i(heapsize);
  while (i > 1 and A[parent(i)].key > A[i].key) {
    std::swap(A[parent(i)], A[i]);
    i = parent(i);  
  }
}


/*******************
 *** extract_min
 *******************/
std::string priority_queue::extract_min()  //remove the string of lowest key and return that string
{
  if (heapsize == 0) {
    throw priority_queue_underflow();
  }

  std::string ans = A[1].object;
  A[1] = A[heapsize];
  --heapsize;
  heapify(1);
  return ans;        
}


/**********************************
 *** function operator overload
 **********************************/
priority_queue::operator std::string()
{
  std::stringstream text; 
  int i(1);  

  while (i <= size) { 
    text << A[i].object << std::endl;
    ++i;
  } 
  return text.str(); 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

叫思念不要吵 2024-12-01 02:08:13

您应该尝试找出遇到麻烦的最小问题。如果您能准确缩小问题范围,会更容易提供帮助。

如果您无法理解如何在数组上下文中使用示例中的 pair 类,那么下面的小(独立)示例可能会有所帮助:

#include <iostream>
#include <string>

class pair {
public:
    std::string object;
    double key;
};

void print_pair(const pair& p) {
    std::cout << p.object << " = " << p.key << std::endl;
}

int main() {

    // allocated on the stack, dies at the end of the function
    pair p;

    p.object = "question";
    p.key = 42;
    print_pair(p);

    pair* pp = new pair();
    (*pp).object = "6 * 10";  // We need to dereference the pointer, kinda clumsy syntax
    pp->key = 60; // Luckily there's a short hand! pp[0].key = 60; is the same thing
    print_pair(*pp);
    delete pp; // remember to clean up!

    pair* ap = new pair[10]; // allocate 10 pairs
    ap[0].object = "zero"; 
    (*(ap + 0)).key = 0; // same thing, ap[N] is the same as *(ap + N)
    print_pair(ap[0]);
    delete []ap; // remember to use the [] syntax when you new'ed like that!
}

You should try to extract the smallest problem you're having trouble with. It would be easier to help if you could narrow down exactly what your question is.

If you're having trouble understanding how to use the pair class from your example in an array context maybe the following small (self-contained) example will help:

#include <iostream>
#include <string>

class pair {
public:
    std::string object;
    double key;
};

void print_pair(const pair& p) {
    std::cout << p.object << " = " << p.key << std::endl;
}

int main() {

    // allocated on the stack, dies at the end of the function
    pair p;

    p.object = "question";
    p.key = 42;
    print_pair(p);

    pair* pp = new pair();
    (*pp).object = "6 * 10";  // We need to dereference the pointer, kinda clumsy syntax
    pp->key = 60; // Luckily there's a short hand! pp[0].key = 60; is the same thing
    print_pair(*pp);
    delete pp; // remember to clean up!

    pair* ap = new pair[10]; // allocate 10 pairs
    ap[0].object = "zero"; 
    (*(ap + 0)).key = 0; // same thing, ap[N] is the same as *(ap + N)
    print_pair(ap[0]);
    delete []ap; // remember to use the [] syntax when you new'ed like that!
}
李白 2024-12-01 02:08:13

好的,终于明白了...谢谢 errbody :-)

/**
* implementing the priority queue as a binary heap
*
*/

#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>
#include <map>
#include <algorithm>

#include "binary_heap.hpp"

/***********************
 *** inline functions
 ***********************/
inline int left(int i) { return i << 1; }

inline int right(int i) { return i << 1 | 1; }

inline int parent(int i) { return i >> 1; }


/*********************
 *** constructor
 *********************/
priority_queue::priority_queue(int n)  
{
  heapsize = 0;
  size = n;

  // don't forget to allocate the array of size n+1 as we don't use slot zero 
  A = new pair[n+1];
}


/*********************
 *** destructor
 *********************/
priority_queue::~priority_queue()  //delete the array
{
  delete[] A;
}


/*******************************************
 *** heapify * finds max of three things
 *******************************************/
void priority_queue::heapify(int k)
{
  pair smallest = A[k];
  int pos = k;        

  //only treat child as object if it's inside heap
  if (left(k) <= heapsize and A[left(k)].key < A[pos].key) {

    // update variables
    smallest = A[left(k)];
    pos = left(k);
  }

  // identical for right
  if (right(k) <= heapsize and A[right(k)].key < A[pos].key) {

    // update variables
    smallest = A[right(k)];
    pos = right(k);
  }

  // after both if's exectued: smallest is pair with smallest key and
  // pos is index of that pair in A[]

  // only need to do something if pos is NOT the same position
  // that we were passed in originally
  if (pos != k) {

    // swap items
    std::swap(A[k], A[pos]);

    // go recursive to trickle down...
    heapify(pos);
  }
}


/****************
 *** empty
 ****************/
bool priority_queue::empty()
{
  return (heapsize == 0);
}


/****************
 *** insert
 ****************/
void priority_queue::insert(std::string s, double priority)  //add s to the heap with the given priority as its key
{
  if (heapsize == size) {
    throw priority_queue_overflow();
  }

  // make room for insert
  ++heapsize;  
  // assign string arg to object member
  A[heapsize].object = s;
  // assign priority arg to key member
  A[heapsize].key = priority;

  // loop through and trickle up as needed
  int i(heapsize);
  while (i > 1 and A[parent(i)].key > A[i].key) {
    std::swap(A[parent(i)], A[i]);
    i = parent(i);  
  }
}


/*******************
 *** extract_min
 *******************/
std::string priority_queue::extract_min()  //remove the string of lowest key and return that string
{
  if (heapsize == 0) {
    throw priority_queue_underflow();
  }

  std::string ans = A[1].object;
  A[1] = A[heapsize];
  --heapsize;
  // trickle down as needed
  heapify(1);
  return ans;        
}


/**********************************
 *** function operator overload
 **********************************/
priority_queue::operator std::string()
{
  std::stringstream text; 
  int i(1);    

  while (i <= size) { 
    text << A[i].object << std::endl;
    ++i;
  } 
  return text.str(); 
}

ok, finally got it... thanks errbody :-)

/**
* implementing the priority queue as a binary heap
*
*/

#include <iostream>
#include <istream>
#include <ostream>
#include <sstream>
#include <map>
#include <algorithm>

#include "binary_heap.hpp"

/***********************
 *** inline functions
 ***********************/
inline int left(int i) { return i << 1; }

inline int right(int i) { return i << 1 | 1; }

inline int parent(int i) { return i >> 1; }


/*********************
 *** constructor
 *********************/
priority_queue::priority_queue(int n)  
{
  heapsize = 0;
  size = n;

  // don't forget to allocate the array of size n+1 as we don't use slot zero 
  A = new pair[n+1];
}


/*********************
 *** destructor
 *********************/
priority_queue::~priority_queue()  //delete the array
{
  delete[] A;
}


/*******************************************
 *** heapify * finds max of three things
 *******************************************/
void priority_queue::heapify(int k)
{
  pair smallest = A[k];
  int pos = k;        

  //only treat child as object if it's inside heap
  if (left(k) <= heapsize and A[left(k)].key < A[pos].key) {

    // update variables
    smallest = A[left(k)];
    pos = left(k);
  }

  // identical for right
  if (right(k) <= heapsize and A[right(k)].key < A[pos].key) {

    // update variables
    smallest = A[right(k)];
    pos = right(k);
  }

  // after both if's exectued: smallest is pair with smallest key and
  // pos is index of that pair in A[]

  // only need to do something if pos is NOT the same position
  // that we were passed in originally
  if (pos != k) {

    // swap items
    std::swap(A[k], A[pos]);

    // go recursive to trickle down...
    heapify(pos);
  }
}


/****************
 *** empty
 ****************/
bool priority_queue::empty()
{
  return (heapsize == 0);
}


/****************
 *** insert
 ****************/
void priority_queue::insert(std::string s, double priority)  //add s to the heap with the given priority as its key
{
  if (heapsize == size) {
    throw priority_queue_overflow();
  }

  // make room for insert
  ++heapsize;  
  // assign string arg to object member
  A[heapsize].object = s;
  // assign priority arg to key member
  A[heapsize].key = priority;

  // loop through and trickle up as needed
  int i(heapsize);
  while (i > 1 and A[parent(i)].key > A[i].key) {
    std::swap(A[parent(i)], A[i]);
    i = parent(i);  
  }
}


/*******************
 *** extract_min
 *******************/
std::string priority_queue::extract_min()  //remove the string of lowest key and return that string
{
  if (heapsize == 0) {
    throw priority_queue_underflow();
  }

  std::string ans = A[1].object;
  A[1] = A[heapsize];
  --heapsize;
  // trickle down as needed
  heapify(1);
  return ans;        
}


/**********************************
 *** function operator overload
 **********************************/
priority_queue::operator std::string()
{
  std::stringstream text; 
  int i(1);    

  while (i <= size) { 
    text << A[i].object << std::endl;
    ++i;
  } 
  return text.str(); 
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文