zoukankan      html  css  js  c++  java
  • Cpp Chapter 12: Classes and Dynamic Memory Allocation Part3

    12.7 A queue simulation

    ) queue: FIFO(first in first out), just like regular queue in the waiting line
    ) stack: LIFO(last in first out), just like a pile of plates
    ) The queue class interface
    decide a set of attributes of the queue class(the public interface)
    ) The queue class implementation
    use a linked list to represent a queue. A linked list consists of a sequence of nodes, each node contains the information to be held in the list, plus a pointer to the next in the list

    struct Node
    {
        Item item;
        struct Node * next;
    }
    

    The example code shows a singly linked list because each node has a single link to the next node. The pointer in the last node points to NULL or 0, or with C++11 nullptr keyword.
    A data member of the Queue class should point to the first Node of a queue. For convenience, you could also have data members for the last node and the number of nodes in the queue(for quickly adding nodes and detecting full and empty and limit of nodes amount). Also a data member should represent the maximum amount of nodes allowed in the queue.

    class Queue
    {
    private:
        struct Node { Item item; struct Node * next;};
        enum {Q_SIZE = 10};
        Node * front;
        Node * rear;
        int items;
        const int qsize;
        ...
    public:
        ...
    }
    

    ) Code:

    class Queue
    {
    private:
        struct Node { Item item; struct Node * next;};
    ...
    }
    

    nest the struct in the class, giving it class scope to avoid conflict with STL(standard template library).

    ) The class methods
    Recall that you could only initialize a const variable, rather than assign it to specific value. Thus making the constructor

    Queue::Queue(int qs)
    {
        ...
        qsize = qs;
    }
    

    invalid to assign qsize to qs. For that sake, C++ provides member initializer list:

    Queue::Queue(int qs) : qsize(qs)
    {
        ...
    }
    

    which follow the regular constructor with the syntax of " : var(val)". You also have to use member initializer list with references for class members. This syntax could only be used with constructors.

    Adding members to queue:
    1 terminate if the queue is full
    2 create a new node
    3 place proper values into the node
    4 increase the amount of nodes
    5 attach the node to the rear of the sequence

    Removing members in queue
    1 terminate if the queue is empty
    2 save the item of the first node to the passed reference to the function
    3 decrease Node count
    4 save the location of front node(for later deletion)
    5 take the node off the queue by "front = front->next"
    6 delete former first node
    7 if list empty, set rear to NULL

    )Other class methods
    An explicit destructor which guarantee that a queue would be empty when it expires
    A copy constructor and overloading the assignment operator is also required, but you could escape this now:

    class Queue
    {
    private:
        Queue(const Queue & q) : qsize(0) { }
        Queue & operator=(const Queue & q) { return *this;}
    ...
    }
    

    Define these methods as private prevents outside from accessing the methods, thus forbidding Queue copy and assignment. Pass objects by reference to avoid this problem

    ) The customer class
    You need to use data members to represent the customer's arrive time, process time, and provide a function in the public interface to set the data

    Here comes the example:

    // queue.h -- interface for a queue
    #ifndef QUEUE_H_INCLUDED
    #define QUEUE_H_INCLUDED
    
    class Customer
    {
    private:
        long arrive;
        int processtime;
    public:
        Customer() {arrive = processtime = 0;}
        void set(long when);
        long when() const {return arrive;}
        int ptime() const {return processtime;}
    };
    
    typedef Customer Item;
    
    class Queue
    {
    private:
        struct Node {Item item; struct Node * next;};
        enum {Q_SIZE = 10};
    
        Node * front;
        Node * rear;
        int items;
        const int qsize;
    
        Queue(const Queue & q); // prevent outside access to copy constructor
        Queue & operator=(const Queue & q) {return *this;} // prevent outside access to assignment operator
    public:
        Queue(int qs = Q_SIZE);
        ~Queue();
        bool isempty() const;
        bool isfull() const;
        int queuecount() const;
        bool enqueue(const Item & item);
        bool dequeue(Item & item);
    };
    #endif // QUEUE_H_INCLUDED
    
    // queue.cpp -- Queue and Customer methods
    #include "queue.h"
    #include <cstdlib>
    
    Queue::Queue(int qs) : qsize(qs)
    {
        front = rear = NULL;
        items = 0;
    }
    
    Queue::~Queue()
    {
        Node * temp;
        while (front != NULL)
        {
            temp = front;
            front = front->next;
            delete temp;
        }
    }
    
    bool Queue::isempty() const
    {
        return items == 0;
    }
    
    bool Queue::isfull() const
    {
        return items == qsize;
    }
    
    int Queue::queuecount() const
    {
        return items;
    }
    
    bool Queue::enqueue(const Item & item)
    {
        if (isfull()) return false;
        Node * add = new Node;
        add->item = item;
        add->next = NULL;
        items++;
        if (front == NULL)
            front = add;
        else
            rear->next = add;
        rear = add;
        return true;
    }
    
    bool Queue::dequeue(Item & item)
    {
        if (isempty()) return false;
        Node * temp = new Node;
        temp = front;
        item = front->item;
        items--;
        front = front->next;
        delete temp;
        if (items == 0)
            rear = NULL;
        return true;
    }
    
    void Customer::set(long when)
    {
        processtime = std::rand() % 3 + 1;
        arrive = when;
    }
    
    // queue.cpp -- Queue and Customer methods
    #include "queue.h"
    #include <cstdlib>
    
    Queue::Queue(int qs) : qsize(qs)
    {
        front = rear = NULL;
        items = 0;
    }
    
    Queue::~Queue()
    {
        Node * temp;
        while (front != NULL)
        {
            temp = front;
            front = front->next;
            delete temp;
        }
    }
    
    bool Queue::isempty() const
    {
        return items == 0;
    }
    
    bool Queue::isfull() const
    {
        return items == qsize;
    }
    
    int Queue::queuecount() const
    {
        return items;
    }
    
    bool Queue::enqueue(const Item & item)
    {
        if (isfull()) return false;
        Node * add = new Node;
        add->item = item;
        add->next = NULL;
        items++;
        if (front == NULL)
            front = add;
        else
            rear->next = add;
        rear = add;
        return true;
    }
    
    bool Queue::dequeue(Item & item)
    {
        if (isempty()) return false;
        Node * temp = new Node;
        temp = front;
        item = front->item;
        items--;
        front = front->next;
        delete temp;
        if (items == 0)
            rear = NULL;
        return true;
    }
    
    void Customer::set(long when)
    {
        processtime = std::rand() % 3 + 1;
        arrive = when;
    }
    

  • 相关阅读:
    %EF%BB%BF问题
    java 性能调优总结
    Mysql 批量数据插入- 插入100万条数据
    中医-常见病-疗法
    windows Oracle 卸载注册表清理脚本
    Redis 关键点剖析
    JPA教程
    Xcode8 iOS10 中权限适配
    textField设置输入文字距左边的距离
    调用手机相册,相册语言选择,
  • 原文地址:https://www.cnblogs.com/fsbblogs/p/9807992.html
Copyright © 2011-2022 走看看