【问题标题】:My queue does not update as I am enqueuing and dequeueing我的队列没有更新,因为我正在入队和出队
【发布时间】:2020-04-01 19:50:25
【问题描述】:

我正在学习队列,我正在努力使用链表来实现这个实现。下面在我的代码中,我试图实现入队和出队方法,但是当我实现这些方法时,我的链接列表无法更新。我觉得这可能与我的指针有关。任何建议或帮助将不胜感激。

#include <iostream>
using namespace std;

// A linked list node 
class Node 
{ 
  public:
    int data; 
    Node *next;
    Node()
    {
      data = 0;
      next = nullptr;
    }
    Node(int data)
    {
      this->data = data;
      next = nullptr;
    }
}; 

class List 
{ 
  public:
    struct Node* head;
    struct Node* tail;
    List()
    {
      head = tail = nullptr;
    }
}; 

void ListPrint(List *list)
{
  Node *tempNode = list->head;
  while(tempNode != nullptr){
    cout<<tempNode->data<<",";
    tempNode = tempNode->next;

  }
}


void ListAppend(List *list, Node *newNode)
{
   if(list->head == nullptr)
   {
      list->head = newNode;
      list->tail = newNode;
   }
   else{
      list->tail->next = newNode;
      list->tail = newNode;
   }
}

void ListRemoveAfter(List *list, Node *curNode) {
   // Special case, remove head
   Node *sucNode;
   if (curNode == nullptr && list->head != nullptr) {
      sucNode = list->head->next;
      //delete(list->head);
      list->head = sucNode;

      if (sucNode == nullptr) { // Removed last item
         list->tail = nullptr;
      }
   }
   else if (curNode->next != nullptr) {
      sucNode = curNode->next->next;
      //delete(curNode->next);
      curNode->next = sucNode;

      if (sucNode == nullptr) { // Removed tail
         list->tail = curNode;
      }
   }
}
void enqueue(List *queue, Node *newItem)
{
  ListAppend(queue, newItem);
  ListPrint(queue);
}

Node dequeue(List *queue)
{
  Node poppedItem = queue->head-> data;
  ListRemoveAfter(queue, nullptr);
  return poppedItem;
}

void isEmpty(List *queue)
{

}
int main() {
  List *myQueue= new List;
  int data;
  char input;

  do
  {
    cout<<"\nCurrent Queue: ";
    ListPrint(myQueue);
    cout<<endl;
    cout<<"\nEnter Queue operation: ";
    cout<<"Enqueue(e), dequeue(d), quit(q): ";
    cin>>input;
    switch(input)
    {
      case 'e':
        cout<<"enter data to enqueue: ";
        cin>>data;
        enqueue(myQueue, new Node(data));
        break;

      case 'd':
        if(!isEmpty(myQueue)){
          Node* poppedItem = dequeue(myQueue);
          cout<<"Dequeued: "<<poppedItem->data;
          delete(poppedItem);
        }
        else
          cout<<"Queue Empty";
       break;

    }

  }while(input != 'q');
}

【问题讨论】:

  • 这是您的实际代码吗?它无法编译。
  • 这段代码无法编译,dequeu 也返回数据而不是指针。

标签: c++ node.js linked-list queue


【解决方案1】:

代码本身正在工作,尽管在​​当前状态下没有编译(添加了一个编辑以使其编译)。当它编译时,我在将项目排入队列时得到正确的输出。

然而,代码远非

  1. 首先,它不是 C++ 代码,而是带有一些 C++ 符号的 C - 没有使用类,它创建了这些 ListPrintListAppend 是 100% C 函数。
  2. 不遵循Queue的API(FIFO,意思是no remove after!)。
  3. 使用原始指针很容易导致内存泄漏(这是 C++11 之后的不良做法)。

看下面的代码:

#include <stdint.h>
#include <memory>
#include <iostream>

template <typename T>
class Queue
{
public:
    T pop()
    {
        if (size > 0)
        {
            T ret_val = head->data;
            if (size == 1)
            {
                head = nullptr;
                tail = nullptr;
            }
            else
            {
                head = head->next;
            }

            --size;

            return ret_val; // here the previous head has no more references, thus deleted.
        }
        else
        {
            // some error handling.
        }
    }

    void push(T value)
    {
        std::shared_ptr<Node<T>> node = std::shared_ptr<Node<T>>(new Node<T>(value));

        if (size == 0)
        {
            head = node;
            tail = node;
        }
        else
        {
            tail->next = node;
            tail = node;
        }

        ++size;
    }

    void print() const
    {
        if (size == 0)
        {
            std::cout << "Empty Queue" << std::endl;
        }
        else
        {
            std::shared_ptr<Node<T>> node = head;

            std::cout << "Queue of size " << size << ": ";

            while (node != nullptr)
            {
                std::cout << node->data << ",";
                node = node->next;
            }

            std::cout << std::endl;
        }
    }

    bool isEmpty() const { return size == 0; }

private:
    template <typename S>
    struct Node
    {
        S data;
        std::shared_ptr<Node<S>> next;

        Node(S data) :
            data(data),
            next(nullptr)
        {
        }
    };

    std::shared_ptr<Node<T>> head = nullptr;
    std::shared_ptr<Node<T>> tail = nullptr;
    uint64_t size = 0;
};



int main()
{
    Queue<int> q;

    q.print();

    for (int i = 0; i < 10; ++i)
    {
        q.push(i);
        q.print();
    }

    for (uint64_t i = 0; i < 10; ++i)
    {
        std::cout << "Popped: " << q.pop() << std::endl;
        q.print();
    }
}

它的输出是:

Empty Queue
Queue of size 1: 0,
Queue of size 2: 0,1,
Queue of size 3: 0,1,2,
Queue of size 4: 0,1,2,3,
Queue of size 5: 0,1,2,3,4,
Queue of size 6: 0,1,2,3,4,5,
Queue of size 7: 0,1,2,3,4,5,6,
Queue of size 8: 0,1,2,3,4,5,6,7,
Queue of size 9: 0,1,2,3,4,5,6,7,8,
Queue of size 10: 0,1,2,3,4,5,6,7,8,9,
Queue of size 9: 1,2,3,4,5,6,7,8,9,
Queue of size 8: 2,3,4,5,6,7,8,9,
Queue of size 7: 3,4,5,6,7,8,9,
Queue of size 6: 4,5,6,7,8,9,
Queue of size 5: 5,6,7,8,9,
Queue of size 4: 6,7,8,9,
Queue of size 3: 7,8,9,
Queue of size 2: 8,9,
Queue of size 1: 9,
Empty Queue

正如预期的那样。

此代码使用类(您的代码中完全缺少的东西!)、简化的弹出算法、处理内存管理的智能指针,并且能够保存任何类型的数据,而不仅仅是整数!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-07
    • 1970-01-01
    相关资源
    最近更新 更多