2011-07-14 54 views
1

已取得进展,但仍无法揣摩出我的无限循环是优先级队列......C++二进制堆

头文件:

#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(); 
} 
+0

您的'pair'类没有任何私人成员? (你也可以用'std :: pair '从''替换它)。但我不确定你在问什么,请你澄清一下? – user786653

+0

errr对不起 - 这两个公共成员,对象和键,需要存储在一个数组中,但我不明白如何单独访问每个成员,以及他们需要在构造函数中初始化的地方/方式 – Bill

+2

您的问题是在'priority_queue :: insert'中获得'A [heapsize] = priority'才能正常工作?你应该编辑你的问题,并强调你在哪里遇到问题。 (顺便说一句:这应该是'A [heapsize] .object = s; A [heapsize] .priority = priority;'和'++ heapsize'应该在之后*我认为*) – user786653

回答

0

OK,终于得偿所愿。 ..谢谢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(); 
} 
2

你应该尝试提取你遇到的最小问题。如果你能够精确地缩小你的问题的范围,帮助会更容易。

如果你无法理解如何使用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! 
} 
+0

非常有帮助,谢谢。对于在数组上下文中使用的pair类非常困惑。 – Bill