帮助链表模板

时间:2011-04-08 03:00:55

标签: c++ g++ linked-list

我的链表需要一些帮助。我认为问题出在复制构造函数或赋值重载中。当我打电话时它会不断给出我的分段错误: (队列test_int_copy(test_int);) 您可以看到的任何其他错误或不良实现也将非常有帮助。 .h文件

#ifndef QUEUE_H
#define QUEUE_H

template <class Object>
class Queue
{
 public:
     Queue();
     //initializes empty queue

     Queue(const Queue& a_queue);
     //copy constructor

     Queue& operator =(const Queue& rhs);
     //overload assignment operator

     bool enqueue(const Object& d);
     //insert object into queue,return true
     //return false if not

     bool dequeue(Object& d);
     //remove object from queue,return true
     //if empty return false

     bool isEmpty();
     //check if empty

     ~Queue();
     //destructor

private:
    struct ListNode
    {
        Object obj;
        //object that is in the list

        ListNode *next;
        //pointer to the next node

    };
    //struct of list

    ListNode *head;
    //pointer that points to head
};

#endif //Queue_H
#include "queue.cpp"  //include queue.cpp with file

.cpp文件

     #include <iostream>
using namespace std;

template <class Object>
Queue<Object>::Queue()
{
    head = NULL;
}

template <class Object>
Queue<Object>::Queue(const Queue<Object> &a_queue)
{
    head = NULL;
  ListNode *nodePtr = a_queue.head;
    while (nodePtr){
      enqueue(nodePtr->obj);
      nodePtr = nodePtr->next;
    }

}

template <class Object>
Queue<Object>& Queue<Object>::operator =(const Queue<Object> &rhs)
{
    //head = NULL;
  ListNode *nodePtr = rhs.head;
  Object temp;
    while(head){
      dequeue(temp);
    }
    while (nodePtr){
      enqueue(nodePtr->obj);
      nodePtr = nodePtr->next;
    }
}

template <class Object>
bool Queue<Object>::enqueue (const Object& d) //Enqueue
{
    ListNode *newNode = new ListNode;
    newNode->obj = d;
    newNode->next = NULL;
    ListNode *nodePtr = NULL;
    ListNode *previousNode = NULL;

    if(isEmpty()){
        head = newNode;
        return true;
        }
    else{
        nodePtr = head;
        while(nodePtr != NULL){
            previousNode = nodePtr;
            nodePtr = nodePtr->next;
        }
        if(previousNode->next == NULL){
            previousNode->next = newNode;
            return true;
        }
        else
            return false;
    }
}

template <class Object>
bool Queue<Object>::dequeue (Object& d)  //Dequeue
{
    ListNode *nodePtr;

    if(!head)
        return false;
    else{
      if(head->next != NULL){
            nodePtr = head;
            d = nodePtr->obj;
            head = head->next;
            delete nodePtr;
            return true;
      }
      else{
        d = head->obj;
        head = NULL;
        return true;
      }
    }
}


template <class Object>
bool Queue<Object>::isEmpty() //Check if Empty
{
    if(!head)
        return true;
    else
        return false;
}

template <class Object>
Queue<Object>::~Queue()   //Destructor
{
    Object temp;
    while(head)
        dequeue (temp);
}

4 个答案:

答案 0 :(得分:2)

也不要包含这样的源文件。或者如果你坚持,一定要把它放在包含警卫内。 e.g。

#include "queue.cpp"  //include queue.cpp with file
#endif //Queue_H

否则,如果多次包含标题(这种情况一直发生),则会出现编译错误。 (STuff将被定义多次)。

此外,如果您要在标题中包含“source” - 确保所有函数都是“内联”(隐式或显式),否则您将收到链接器错误

答案 1 :(得分:1)

我可以看到一个错误:在dequeue()方法中,删除最后一项后不要将head设置为NULL。

另外,在赋值重载中:

while(head){
      dequeue(temp);
      head = head->next;
    }

...你不需要设置head = head-&gt;接下来,这已经由dequeue()方法完成了。

答案 2 :(得分:1)

  1. 您的enqueue()函数总是在最后插入一个节点。因此,最好将额外的成员变量维护为:ListNode *tail;指向列表的最后一个节点。因此,当您添加节点时,您不需要遍历整个列表,只需更新*tail即可。这将节省大量时间。
  2. 出于任何原因,您从false返回enqueu(),请不要忘记delete newNode;否则会泄漏内存。
  3. isEmpty()您可以简化为bool isEmpty() { return (0 != head); }
  4. 而不是声明&amp;在dequeue()中传递原始对象,如果删除了元素,则只需返回Object*,如果元素为空则返回0 (NULL);这相当于truefalse
  5. 重要的是,只要您delete head;总是head = 0;。因为那是一个成员变量,不应该悬空。

答案 3 :(得分:1)

您应该在复制构造函数中初始化头指针(顺便说一句,也可以在operator =函数中)。如果你不这样做,head可能会以未定义的值结束并且未通过IsEmpty测试,这可能会导致enqeue崩溃。