【问题标题】:queue implementation with vector c++使用向量 C++ 实现队列
【发布时间】:2018-11-10 14:42:33
【问题描述】:

我们被指示实现一个使用向量来存储队列的类。我想出了以下内容,但它并没有真正起作用。谁能告诉我出了什么问题?

数字的值被正确地推入 vec,第一个 pop() 工作。但是如果我检查 head->getElement(),它会给出一个奇怪的数字。对 pop() 的后续调用也会失败。

#include <iostream>
#include <vector>
using namespace std;

template<class T>
class node{
    T element;
    node* next;
public:
    node(): next(nullptr){};
    T getElement() {return element;}
    void setElement(T newElement) {element=newElement;}
    node* getNext() {return next;}
    void setNext(node* newNext) {next = newNext;}
};

template<class T>
class queue{
    vector<node<T>> vec;
    node<T>* head;
    int size;
public:
    queue(): head(nullptr){}
    void push(node<T> newNode);
    node<T> pop();
    int getSize() {return unsigned(vec.size());}
    vector<T> getVec()const {return vec;}
    node<T>* getHead() {return head;}
    void setHead(node<T>* newHead) {head = newHead;}
    vector<node<T>> getVec() {return vec;}
};

int main() {
    queue<int> v;

    for (int i=0;i<5;i++){
        node<int>* newNode = new node<int>;
        newNode->setElement(i);
        v.push(*newNode);
    }
    cout<<"The elements in the vector are initially:\n";
    for (int i=0; i<v.getSize();i++)
        cout<<v.getVec()[i].getElement()<<" ";
    cout<<"\nAfter popping, the popped element is "<<v.pop().getElement()<<endl;
}

template<class T>
node<T> queue<T>:: pop(){
    node<T>* tmp = new node<T>;
    tmp->setNext(head->getNext());
    head=head->getNext();
    return *tmp;
}

template<class T>
void queue<T>:: push(node<T> newNode){
    if (head==nullptr){
        node<T>* newPtr = new node<T>;
        newPtr = &newNode;
        newPtr->setNext(head);
        head=newPtr;
    }
    else{
        node<T>* newPtr = new node<T>;
        newPtr->setElement(newNode.getElement());
        node<T>* end = head;
        while (end->getNext() != nullptr)
            end->setNext(end->getNext());
        end->setNext(newPtr);
    }
    vec.push_back(newNode);
}

【问题讨论】:

    标签: c++ queue


    【解决方案1】:

    您的代码存在许多问题。 首先,让我们修复pop。您正在创建一个新节点 tmp,设置下一个并返回相同而不设置元素。要解决此问题,您只需将其设置为 head 并将 head 移动到下一个。

    template<class T>
    node<T> queue<T>:: pop(){
    node<T>* tmp = head;// = new node<T>;
    //tmp->setNext(head->getNext());
    head=head->getNext();
    return *tmp;
    }
    

    在此之后,您将获得带有 pop 的元素。但是你会得到错误的元素。由于队列是基于 FIFO 的,因此您应该在第一次弹出时获得“0”,但在您的情况下,您不会获得 0。因为,您的推送功能也不正确。在推送中,当您推送第一个元素时,您将获取按值传递的节点对象的地址,这会导致未定义的行为,因为一旦函数完成,传递的节点对象将被销毁。此外,在您推送的 else 部分中,您将 end 的下一个设置为它自己的下一个,因此它将进入无限循环。下面是更正后的实现。

    template<class T>
    void queue<T>:: push(node<T> newNode){
    if (head==nullptr){
        node<T>* newPtr = new node<T>;
        newPtr->setElement(newNode.getElement());
        //newPtr = &newNode;
        //newPtr->setNext(head);
        head=newPtr;
    }
    else{
        node<T>* newPtr = new node<T>;
        newPtr->setElement(newNode.getElement());
        node<T>* end = head;
        while (end->getNext() != nullptr)
            end = end->getNext();
        end->setNext(newPtr);
    }
    vec.push_back(newNode);
    }
    

    最后,您的代码中有很多内存泄漏。您正在创建一个新节点的次数远远超过需要的次数,并且也没有删除它们。正如您现在看到的,在推送的情况下,您只需要传递元素 T 就足够了。您不需要每次都传递一个新节点。 另外,请尝试使用智能指针,因为它会自行管理很多事情。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-22
      • 1970-01-01
      • 2020-04-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-07-24
      • 1970-01-01
      相关资源
      最近更新 更多