在c++模板化队列中实现put()函数的建议

Advice on implementing put() function in a c++ templated queue?

本文关键字:函数 put 实现 c++ 队列      更新时间:2023-10-16

我试图实现一个队列,我不允许改变头文件定义,它看起来像这样:

class PQueue
{
  private:
    struct Node
    {
      EType Item;
      unsigned Priority;
      unsigned Identifier;
      Node * Pred;
      Node * Succ;
    };
    Node * Head;    // Pointer to head of chain (front)
    Node * Tail;    // Pointer to tail of chain (back)
  public:
    // Initialize pqueue to empty
    //
    PQueue();
    // De-initialize pqueue
    //
    ~PQueue();
    // Re-initialize pqueue to empty
    //
    void reset();
    // Initialize pqueue using existing pqueue
    //
    PQueue( const PQueue<EType>& );
    // Assign into pqueue from other pqueue
    //
    PQueue<EType>& operator=( const PQueue<EType>& );
    // Display attributes and contents of pqueue
    // (from front to back, or back to front)
    //
    void display( ostream&, Direction ) const;
    // Return number of items in pqueue
    //
    unsigned length() const;
    // Return copy of item at front of pqueue (unless pqueue is empty)
    //
    bool front( EType& ) const;
    // Return copy of item at back of pqueue (unless pqueue is empty)
    //
    bool back( EType& ) const;
    // Insert one item (with specified priority) into pqueue (if possible)
    //
    bool put( const EType&, unsigned );
    // Remove item with highest priority from pqueue (unless pqueue is empty)
    //
    bool get( EType& );
    // Discard item with specified identifier from pqueue (if possible)
    //
    bool discard( unsigned );
};
到目前为止,我有这些构造函数和析构函数:
template <typename EType> PQueue::PQueue() {
    Head->Pred = NULL;
    Tail->Succ = NULL;
    Tail->Pred=Head;
    Head->Succ=Tail;
} 
template <typename EType> PQueue::~PQueue() {
    reset();
    delete Head;
    Head = NULL;
    delete Tail;
    Tail = NULL;
}

现在我被困在put()上,我不知道从哪里开始,有帮助吗?

您应该分配一个节点,并将其挂接到列表中。

:

   template <typename EType>
   bool PQueue::put( const EType& et, unsigned pri ) {
      Node *p = new Node ();
      p->Item = et;
      p->priority = pri;
// now hook it into the list
   p->pred = NULL;
   head = p;
   }

然而,这是不够的,因为你没有在构造函数中正确初始化head和tail;以至于我不知道你是在创建单链表还是双链表。在您当前的代码中,您的代码表现得好像头和尾指向实际的节点,但我不知道这些节点在哪里(或创建在哪里)。

另外,你的一些代码是在EType上模板化的,而其他部分不是。

在转到put()之前,您需要使现有的构造函数和析构函数正确!

如果要设置节点的->Pred->Succ,则节点必须首先存在。Head和Tail 指针指向Node…not instances of Node,所以没有节点可以操作:

如果头和尾本身是节点,情况就不一样了,但是它们会被这样声明:

Node Head;    // head node of chain (front)
Node Tail;    // tail node of chain (back)

…而不是:

Node * Head;    // Pointer to head of chain (front)
Node * Tail;    // Pointer to tail of chain (back)

这在技术上是可以做到的,但是不清楚为什么空且未初始化的队列实现需要存在任何节点。如果您正在创建一个不寻常的队列类,它总是至少有两个元素(出于某种原因),那么您可能会考虑这样的怪事。但你的任务显然不要求这样。

您想要拍摄的规则是空队列(例如刚刚构建的队列)为零 Node s。只需将Head和Tail指针本身设置为NULL,就完成了:

template <typename EType> PQueue::PQueue() {
    Head = NULL;
    Tail = NULL;
} 
有一个特殊的语法来初始化成员,顺便说一下…虽然在这种情况下是否使用赋值语句进行初始化并不重要,但在某些情况下,比如基类初始化,你必须这样做:
template <typename EType> PQueue::PQueue() :
    Head (NULL),
    Tail (NULL)
{
} 

因此,如果规则(或"不变量")是空队列的头和尾为空,那么调用reset()应该使您处于头和尾为空的状态。然而,如果头和尾都是NULL,那么为什么要在析构函数中删除它们呢?这在技术上是安全的:

删除NULL指针安全吗?

但是没有效果。reset()调用应该足以实现析构函数的工作,以释放任何非空队列的所有已分配节点…如果队列为空,reset()应该足够聪明,什么也不做:

template <typename EType> PQueue::~PQueue() {
    reset();
}

至于我对继续进行put()的建议…嗯…看起来您需要阅读一些书籍,了解语言和数据结构的基本问题。通过简单的链表工作……没有模板…让其中一个工作:

http://en.wikipedia.org/wiki/Linked_list