顺序栈比较容易实现但是顺序队列会有一些小问题,在网上看了很多博客但是下面两个问题我没有找到说的比较详细的,所以在我觉得自己弄明白以后写这篇博客来记录一下。
一、当实现顺序队列的时候空出来第一位置比较好还是空出来最后一个位置比较好?
答案:空出来第一个位置更好,顺序队列为了实现方便通常会空出来一个位置不使用,这样类似于rear=(rear+1)%capacity这种写法可以很容易实现,而空出来以后当front与rear相等的时候我们才可以判断出来队列为空,如果不留一个空位置,当这俩相等的时候可能满了也可能为空;而当空出来最后一个位置的时候,如果写返回最后一个数据的函数的时候需要对rear=0的情况进行特殊分析,不能直接写return queue[rear-1],比较麻烦,但是空出来第一个位置的时候返回front与返回rear的函数都比较容易实现。
二、顺序队列的自动扩容函数到底应该怎么书写?
答案:顺序队列如果没有自动扩容功能那么它基本上是没有任何实用价值,肯定去写链式队列了,他需要分为两种情况:
一种是没有经过pop,不断push然后队列满了;一种是经过了pop,然后push队列满了的情况;其实就是队首在前队尾在后与队尾在前队首在后的两种情况!第一种情况直接复制到新的数组中去就可以了但是第二种复制的时候就要讲究了但也并不复杂下面是代码实现相信一看就明白了:
template<class T>
class Queue
{
public:
Queue(int queueCapacity = 10);
bool IsEmpty()const;
T& Front()const;
T& Rear()const;
void Push(const T&item);
void Pop();
private:
T*queue;
int front;
int rear;
int capacity;
};
template<class T>
Queue<T>::Queue(int queueCapacity=10):capacity(queueCapacity){
if (capacity < 1)
cout << "队列容量不能小于1!" << endl;
queue = new T[capacity];
front = rear = 0;
}template<class T>
bool Queue<T>::IsEmpty()const{
return front == rear;
}
template<class T>
void Queue<T>::Push(const T&item){
if ((rear + 1) % capacity == front)
{
cout << "队列满了!" << endl;
T*newQ = new T[capacity * 2];
int start = (front + 1) % capacity;
if (start < 2)//第一种情况也就是没有pop的情况一直在推进来数据最后满了
copy(queue + start, queue + start + capacity - 1, newQ);//属于第一种情况直接复制就行
else//发生了pop以后然后满了队尾跑在了队首的前面
{
copy(queue + start, queue + capacity, newQ+1);//其他的就属于第二种情况最后加1继续让第一个位置空出来
copy(queue, queue + rear + 1, newQ + capacity - start+1);//同样也记得加1
front = 0;
rear = capacity - 1;
}
capacity *= 2;
delete[]queue;
queue = newQ;
}
rear = (rear + 1) % capacity;
queue[rear] = item;
}template<class T>
T& Queue<T>::Front()const{
return queue[(front+1)%capacity];
}template<class T>
T& Queue<T>::Rear()const{
return queue[rear];
}template<class T>
void Queue<T>::Pop(){
front = (front + 1) % capacity;
queue[front].~T();
}以上就是代码,肯定有不好的地方希望大家可以指出来,大家一起学习进步!
版权声明:本文为qiexinyueaifei原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。