【问题标题】:Custom Queue Class C++自定义队列类 C++
【发布时间】:2012-11-26 19:58:41
【问题描述】:

所以我正在尝试创建一个单链表队列。我正在尝试编写一个添加元素的函数,一切都很好,但问题是它的 FILO 而不是 FIFO。我不确定如何处理前后指针。

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

class Queue{
    public:
        Queue();
       //~Queue();
       void add(const string & item);
       //string remove();
      // unsigned items() const;
       void show() const;
    private:
        struct Node{
            string data;
            Node *next;
        };
        Node *rear;
        Node *front;
        unsigned elements;
};

Queue::Queue():elements(0),rear(NULL),front(NULL){}

//Queue::~Queue(){

//}

void Queue::add(const string & item){
    Node *t=new Node;
    t->data=item;
    t->next=rear;
    if(front==NULL)
        front=t;
    rear=t;
    elements++;

}

void  Queue::show() const{

    Node *p=rear;
    for(; p->next!=rear; p=p->next){
        cout<<" "<<p->data;
    }
    cout<<"\n";
}
int main(){
    Queue obj;
    obj.add("I");
    obj.add("Am");
    obj.add("Super");
    obj.add("Cool");
    obj.show();
}

【问题讨论】:

  • 在您编写 remove 函数之前,无法判断它是 FIFO 还是 LIFO,因为什么都不会输出!
  • 你似乎跳过了在纸上画小方框和箭头的步骤。

标签: c++ class queue singly-linked-list


【解决方案1】:

目前既不是 FIFO 也不是 FILO bu JINO(刚进,永不出)。

你所做的就是在后端插入。而且你的节目确实从后到前迭代,因为那是唯一的链接方向。

要获得有效的 FIFO,您需要从队列的前端移除。你会注意到,你可以找到前面的元素,但是你没有简单的方法来找到设置前面指针所需的第二个元素。这是单链接设计的缺点,您必须从后到前迭代才能找到指向前的元素。

  • 使用单个链表,您可以执行 FILO(实际上更可能命名为 LIFO 或堆栈)
  • 对于 FIFO,双链表会是更好的设计。

如果你想坚持一个单一的链表,你可以做一些递归。你消除了前指针,因为它没用。

void  Queue::show_one(Node *p) const{
    if (p->next!=rear) {    // i kept the test for p->next!=rear
                            // either fix add or test for p->next!=NULL
        show_one(p->next);
    }
    cout<<" "<<p->data;
}

void  Queue::show() const{
    show_one(rear);
    cout<<"\n";
}

同样你可以写一个remove()

【讨论】:

  • 如何反转链表的方向?我的最后一个节点应该是空节点,我的后部应该指向空节点。以下代码使所有内容都正确输出,但我不喜欢复制每个元素然后输出它。无效队列::show() const { string * t = NULL; t = 新字符串[元素];节点 * p = 后方; for( 无符号 i = 0; i next ) t[i] = p->data; for( 无符号 i = 元素; i--; ) cout
【解决方案2】:

要实现,FILO(像STACK?), 当 push(add) 时,在末尾追加新元素(您将处理后指针) pop时,去掉rear指针指向的元素。

在您的代码中,您的后指针指向结束后的一个元素,该元素为空。所以 push 需要 O(n),pop 需要 O(n)。它效率不高。所以考虑双链表可能是更容易实现的更好选择。

【讨论】:

    【解决方案3】:

    我想出了如何扭转整个事情,使它现在可以正常工作。它有效率吗? main 运行耗时 1.06ms。

        #include <iostream>
        #include <string>
        using namespace std;
        bool die(const string &msg);
    
        class Queue{
            public:
                Queue();
               ~Queue();
               void add(const string & item);
               string remove();
               unsigned items() const;
               void show() const;
            private:
                struct Node{
                    string data;
                    Node *next;
                };
                Node *rear;
                Node *front;
                unsigned elements;
        };
    
        Queue::Queue():elements(0),rear(NULL),front(NULL){}
    
        Queue::~Queue(){
         unsigned el=items();
         for(unsigned i=0; i<el; i++)
          remove();
        }
        unsigned Queue::items()const{
            return elements;
        }
    
        string Queue::remove(){
            if(front==NULL) die("underflow");
            Node *t=front;
            string data=t->data;
            front=t->next;
            delete t;
            elements--;
            return data;
        }
        void Queue::add(const string &item){
         Node *t=new Node;
         t->data=item;
         t->next=NULL;
         if(front==NULL)
            front=t;
         else{
            Node *t2=rear;
            t2->next=t;
         }
         rear=t;
         elements++;
        }
    
        void  Queue::show() const{
            Node *t=front;
            for(unsigned i=0; i<items(); i++, t=t->next)
                cout<<t->data<<'\n';
        }
    
        bool die(const string &msg){
            cout<<"Error: "<<msg;
            exit(EXIT_FAILURE);
        }
    
        int main(){
            Queue obj;
            obj.show();
            obj.add("poo");
            obj.add("cra");
            obj.add("bil");
            obj.add("shi");
            obj.show();
            cout<<obj.remove()<<"\n";
            cout<<obj.remove()<<"\n";
            cout<<obj.remove()<<"\n";
            cout<<obj.remove()<<"\n";
        }
    

    【讨论】:

    • 70条添加语句大约需要1.40ms
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多