在C ++中使用链接列表实现CircularQueue

时间:2015-11-01 17:22:22

标签: c++ data-structures queue circular-list

我目前正在做一个项目,需要我在C ++中实现一个CircularQueue数据结构。以下是我到目前为止的情况:

template<typename Type> class CircularQueue {

template<typename Type> struct CQNode {
    Type head;
    CQNode* tail;

    CQNode() {
        this->head = NULL;
        this->tail = NULL;
    }

    CQNode(Type head, CQNode* tail = NULL) {
        this->head = head;
        this->tail = tail;
    }

};


private:

CQNode<Type>* front;
CQNode<Type>* rear;
CQNode<Type>** circularQueue = NULL;
int MAX = 0;
int currentSize = 0;


protected:

public:

/**********************************************************/
/********************** CONSTRUCTORS **********************/
/**********************************************************/

/**
 * @brief
 * 
 * [DETAILED DESCRIPTION]
 *
 * @param capacity integer size capacity of CircularQueue object to be instantiated
 */
CircularQueue(int capacity) {

    // Set the maximum queue capacity to the size passed to constructor
    this->MAX = capacity;

    // Locally set the limit (to be used as array of CQNode size) to MAX
    const int limit = this->MAX;

    // Create a pointer array of CQNode with size limit and assign to this->circularQueue
    this->circularQueue = new CQNode<Type>*[limit];

    // Loop over queue capacity, implementing CircularQueue type structure
    for (int i = 0; i < limit; i++) {

        // set i'th element of circularQueue array to a new CQNode struct
        this->circularQueue[i] = new CQNode<Type>();

        // if the value of i is greater than 0, assign the tail of the (i-1)'th element 
        // of circularQueue to i'th element of circularQueue, thereby implementing the Queue
        // FIFO type data structure
        if (i > 0) {
            this->circularQueue[i - 1] = this->circularQueue[i];
        }

        // otherwise, if i is equal to the capacity - 1 (i.e. the last elementt of circularQueue array),
        // then set the tail of the last element of circularQueue to the first element of circularQueue,
        // thereby implementing the circular nature of this queue data structure
        else if (i == (limit - 1)) {
            this->circularQueue[i - 1]->tail = this->circularQueue[0];
        }

    }

    this->front = NULL;
    this->rear = NULL;
}

/**********************************************************/
/********************** DESTRUCTORS ***********************/
/**********************************************************/

/**
 * @brief
 *
 * [DETAILED DESCRIPTION]
 *
 */
~CircularQueue() {
    //TODO: Destroy Queue
}

/********************************************************/
/*********************** GETTERS ************************/
/********************************************************/

CQNode<Type>* peekFront() {
    return this->front;
}

CQNode<Type>* peekRear() {
    return this->rear;
}

Type peekHeadOfFront() {

    if (this->front != NULL)
        return this->front->head;

}

int getCurrentSize() {
    return this->currentSize;
}

bool isEmpty() {
    return this->rear == NULL;
}

/**********************************************/
/****************** TOSTRING ******************/
/**********************************************/

/**
 * @brief
 *
 * [DETAILED DESCRIPTION]
 *
 * @return string representation of this CircularQueue object
 */
string toString() {

    string temp = "[";

    CQNode<Type>* tempNode = this->front;

    int i = 0;

    while (tempNode != NULL && i < this->currentSize) {
        i++;
        //cout << temp << endl;
        if (tempNode->tail != NULL) {
            temp += std::to_string(tempNode->head) + ", ";
        }
        else {
            temp += std::to_string(tempNode->head);
        }
        tempNode = tempNode->tail;
    }

    temp += "]";

    return temp;

}

/********************************************************/
/******************* QUEUE OPERATIONS *******************/
/********************************************************/

/**
 * @brief
 *
 * [DETAILED DESCRIPTION]
 *
 * @param item Object to enqueue to this instance of CircularQueue
 * @return The item of data structure "Type" enqueued upon this CircularQueue instance
 */
Type enqueue(Type item) {

    // if the currentSize is greater than the maximum allowed capacity,
    // throw a CircularQueueException
    if (this->currentSize == this->MAX) {
        throw CircularQueueException("Circular queue is full, cannot enqueue any more objects!");
    }

    // if the front of this CQ object is null, assign first element of circularQueue array to 
    // front of queue and set the rear to the front (single-element queue)
    if (this->front == NULL) {
        //this->front = new CQNode<Type>(item);
        this->front = this->circularQueue[0];
        this->rear = this->front;
    }

    // else if the front is not-null, assign the tail of the rear of this CQ object
    // to a new CQNode with head = item, and shift the new rear to tail of old rear
    else {
        this->rear->tail = new CQNode<Type>(item);

        this->rear = this->rear->tail;

        if (this->currentSize == (this->MAX - 1))
            this->rear->tail = this->front;

    }

    this->currentSize++;

    return item;

}

/**
 * @brief
 *
 * [DETAILED DESCRIPTION]
 *
 * @return The item of data structure "Type" dequeued from this CircularQueue instance
 */
Type dequeue() {

    // Create a pointer to a CQNode initialised as NULL
    // this variavle will store the dequeued node
    CQNode<Type>* dequeuedNode = NULL;

    // if rear is empty, throw a CircularQueueException
    if (this->rear == NULL) {
        throw CircularQueueException("Circular queue is already empty, cannot dequeue any objects!");
    }

    else {

        // decrement currentSize of this CircularQueue instance by 1
        this->currentSize--;

        // assign front of this CircularQueue to dequeuedNode
        dequeuedNode = this->front;

        // set the new front of the queue to the tail of the current front
        this->front = this->front->tail;

    }

    return dequeuedNode->head;
}


};

到目前为止,这是一个很好的实现吗?请提及您使用此代码可以看到的任何不良编码做法或潜在问题。

请注意,我的toString()函数被设计为只打印队列的单个“圆圈”,如果有更好的方法为CircularQueue制作toString(),那么请提及它。

0 个答案:

没有答案