链接列表入队和出列

时间:2015-10-26 03:05:22

标签: c++ linked-list queue

我使用c ++对我的队列和队列实现队列的队列出了点麻烦。我的老师说模板是不受限制的,我不能改变公共和私人功能,因为他把它们交给我们。我一直遇到分段错误。我真的不明白我做错了什么。我还包括了标题以及入队和出队功能。

标题

const int MAX_STRING = 6;

typedef char Element300[MAX_STRING + 1];

class Queue300
{

    public:
        Queue300();
        Queue300(Queue300&);
        ~Queue300();
        void enQueue300(const Element300);
        void deQueue300(Element300);
        void view300();

    private:
        struct Node300;
        typedef Node300 * NodePtr300;
        struct Node300
        {
            Element300 element;
            NodePtr300 next;
        };
        NodePtr300 front, rear;
};

入队

void Queue300::enQueue300(const Element300 input)


{
    NodePtr300 temp = NULL;

    temp = new (std::nothrow) Node300;

    if (temp == NULL)
    {
        cerr << "The queue is full, could not add(enqueue) any more elements." << endl;
    }

    else if (front == NULL && rear == NULL)
    {
        strcpy(temp->element, input);
        rear = temp;
        rear->next = NULL;
        front = rear;
        temp = NULL;
    }

    else
    {
        strcpy(temp->element, input);
        temp = rear->next;
        rear = temp;
        rear->next = NULL;
        temp = NULL;
    }
}

出列

void Queue300::deQueue300(Element300 input)



{
    NodePtr300 temp = NULL;

    if (rear == NULL && front == NULL)
    {
        cerr << "The queue is already empty, could not delete(dequeue) any more elements." << endl;
    }

    else if (front == rear)
    {
        strcpy(temp->element, input);
        temp = front;
        delete temp;
        temp = NULL;
        front = NULL;
        rear = NULL;
    }

    else
    {
        strcpy(temp->element, input);
        temp = front;
        front = front->next;
        temp->next = NULL;
        delete temp;
        temp = NULL;
    }
}

2 个答案:

答案 0 :(得分:1)

在enqueue中,当你说&#34; temp = rear-&gt; next&#34;时,你会在temp中覆盖指向新节点的指针。

将新节点添加到链接列表中时,通常最好首先在新节点中设置指针:

temp->next = null;
rear->next = temp;
rear=temp;

此外:

  • 报告错误后,您必须返回。如果你继续,你会崩溃。抛出异常或返回错误代码

  • 会更好
  • 出列的strcpys走错路

  • 为防止缓冲区溢出,你应该使用strncpy而不是strcpy,然后确保目标为空终止,因为Element应该是一个字符串

答案 1 :(得分:0)

让我们来看看Enqueue:

    if (temp == NULL)
    {
        ...
    }
    else if (front == NULL && rear == NULL)
    {
        ...
    }
    else
    {
        strcpy(temp->element, input); // copy input into temp->element

        // temp points to rear->next (it is always NULL, isn't it?)
        // we lost the Node300 previously pointed by temp.
        temp = rear->next; 

        // rear points to the same location as temp (NULL)
        rear = temp;

        // rear->next: dereferencing NULL /!\
        rear->next = NULL;

        temp = NULL;
    }

ASCII艺术的时间。这是在入队之前:

  REAR -------------------
                         |
                         v
          [0]--> ... -->[N]-->NULL
           ^
  FRONT ---|

您分配了一个由[X]引用的节点temp

temp --> [X]

REAR的下一个必须指向同一个节点:

REAR
 |   
 v
[N] --> [X]
         ^
         |
        temp

然后,必须更新REAR以引用[X]。 就指针操作而言,你甚至不需要temp指针,但是让我们保留它,因为你正在检查节点之前是否正确分配,这很好。

rear->next = temp;
rear = temp;       // or rear = rear->next;
temp->next = NULL; // or rear->next = NULL;

另请注意,您在strcpy(temp->element, input);个分支机构中执行了else。您可以在temp == NULL时从函数返回并在检查frontrear是否为NULL之前执行复制。