帮助链接列表模板

发布于 2024-10-30 19:36:14 字数 3181 浏览 0 评论 0原文

我的链接列表需要一些帮助。我认为问题出在复制构造函数或赋值重载中。当我打电话时,它总是给出分段错误: (队列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);
}

I need some help with my linked list. I think the problem is in the copy constructor or the assignment overload. it keeps giving my segmentation fault when i call:
(Queue test_int_copy(test_int);)
Any other error or poor implementation that you can see would also be very helpful.
the .h file

#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

the .cpp file

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

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

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

发布评论

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

评论(4

牵你的手,一向走下去 2024-11-06 19:36:15

也不要像这样包含源文件。或者,如果您坚持,请确保将其放入包含防护中。例如

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

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

另外,如果您要包含标头中的“源”,请确保所有函数都是“内联”(隐式或显式),否则您将收到链接器错误

Also don't include the source file like that. Or if you insist, make sure to put it inside the include guard. e.g.

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

Otherwise if the header is included multiple times (which happens all the time), you'll have a compilation error. (STuff will be defined multipled times).

Also, if you're going to include the "source" from the header -- make sure all functions are "inline" (implicitly or explicitly), otherwise you'll get linker errors

不可一世的女人 2024-11-06 19:36:15

您应该在复制构造函数中初始化头指针(顺便说一下,也在您的运算符 = 函数中)。如果不这样做, head 可能会得到一个未定义的值并无法通过 IsEmpty 测试,这可能会导致排队崩溃。

You should initialize your head pointer in your copy constructor (and also in your operator = function by the way). If you don't do so, head might end up with an undefined value and fail the IsEmpty test, witch may lead to a crash in enqeue.

傻比既视感 2024-11-06 19:36:15

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

另外,在赋值重载中:

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

...您不需要设置 head = head->next,这已经由 dequeue() 方法完成了。

One mistake I can see: in the dequeue() method, you do not set head to NULL after removing the last item.

Also, in the assignment overload:

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

... You do not need to set head = head->next, that has already been done by the dequeue() method.

一曲琵琶半遮面シ 2024-11-06 19:36:15
  1. 您的 enqueue() 函数始终在末尾插入一个节点。因此最好维护一个额外的成员变量:ListNode *tail;指向列表的最后一个节点。因此,当您添加节点时,无需遍历整个列表,只需更新 *tail 即可。这会节省很多时间。
  2. 无论出于何种原因,您从 enqueu() 返回 false,都不要忘记 delete newNode; 否则会泄漏内存。
  3. isEmpty() 你可以简化为 bool isEmpty() { return (0 != head); }
  4. 而不是声明 &在 dequeue() 中传递原始对象,如果元素被删除,您可以简单地返回 Object* ,或者如果元素为空,则返回 0 (NULL) ;这相当于 truefalse
  5. 重要的是,每当您删除 head; 时,始终执行 head = 0;。因为这是一个成员变量,不应该是悬空的。
  1. Your enqueue() function always inserts a node in the end. So it's better to maintain an extra member variable as: ListNode *tail;pointing to the last node of the list. So when you are adding a node you don't need to traverse through whole list and simply update the *tail. This will save lot of time.
  2. For whatsoever reason you return false from enqueu(), do NOT forget to delete newNode; otherwise it will leak memory.
  3. isEmpty() you can simplify as bool isEmpty() { return (0 != head); }.
  4. Instead of declaring & passing a raw object in dequeue(), you can simply return Object* if element is removed or return 0 (NULL) if it's empty; that's equivalent to true and false.
  5. Importantly, whenever you delete head; always do head = 0;. Because that's a member variable and should not be dangling.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文