数组实现可扩展的循环队列

arrayQueue.h

// circular array implementation of a queue
// derives from the ADT queue

#ifndef arrayQueue_
#define arrayQueue_

#include "queue.h"
#include "myExceptions.h"
#include <sstream>

using namespace std;

template<class T>
class arrayQueue : public queue<T>
{
   public:
      arrayQueue(int initialCapacity = 10);
      ~arrayQueue() {delete [] queue;}
      bool empty() const {return theFront == theBack;}
      int size() const
          {return (theBack - theFront + arrayLength) % arrayLength;}
      T& front()
         {// return front element
            if (theFront == theBack)
               throw queueEmpty();
            return queue[(theFront + 1) % arrayLength];
         }
      T& back()
         {// return theBack element
            if (theFront == theBack)
               throw queueEmpty();
            return queue[theBack];
         }
      void pop()
           {// remove theFront element
              if (theFront == theBack)
                 throw queueEmpty();
              theFront = (theFront + 1) % arrayLength;
              queue[theFront].~T();  // destructor for T
           }
      void push(const T& theElement);
   private:
      int theFront;       // 1 counterclockwise from theFront element
      int theBack;        // position of theBack element
      int arrayLength;    // queue capacity
      T *queue;           // element array
};

template<class T>
arrayQueue<T>::arrayQueue(int initialCapacity)
{// Constructor.
   if (initialCapacity < 1)
   {ostringstream s;
    s << "Initial capacity = " << initialCapacity << " Must be > 0";
    throw illegalParameterValue(s.str());
   }
   arrayLength = initialCapacity;
   queue = new T[arrayLength];
   theFront = 0;
   theBack = 0;
}

template<class T>
void arrayQueue<T>::push(const T& theElement)
{// Add theElement to queue.

   // increase array length if necessary
   if ((theBack + 1) % arrayLength == theFront)
   {// double array length
      // allocate a new array
      T* newQueue = new T[2 * arrayLength];

      // copy elements into new array
      int start = (theFront + 1) % arrayLength;
      if (start < 2)
         // no wrap around
         copy(queue + start, queue + start + arrayLength - 1, newQueue);
      else
      {  // queue wraps around
         copy(queue + start, queue + arrayLength, newQueue);
         copy(queue, queue + theBack + 1, newQueue + arrayLength - start);
      }

      // switch to newQueue and set theFront and theBack
      theFront = 2 * arrayLength - 1;
      theBack = arrayLength - 2;   // queue size arrayLength - 1
      arrayLength *= 2;
      queue = newQueue;
   }

   // put theElement at the theBack of the queue
   theBack = (theBack + 1) % arrayLength;
   queue[theBack] = theElement;
}

#endif


main.cpp

// test array queue

#include <iostream>
#include "arrayQueue.h"
#include "myExceptions.h"

using namespace std;

int main(void)
{
   arrayQueue<int> q(4);

   // add a few elements
   q.push(1);
   cout << "Queue rear is " << q.back() << endl;
   q.push(2);
   cout << "Queue rear is " << q.back() << endl;
   q.push(3);
   cout << "Queue rear is " << q.back() << endl;
   q.push(4);
   cout << "Queue rear is " << q.back() << endl;

   cout << "Queue should be 1234, front to rear" << endl;

   // test empty and size
   if (q.empty())
      cout << "The queue is empty" << endl;
   else
      cout << "The queue is not empty" << endl;

   cout << "The queue size is " << q.size() << endl;

   while (!q.empty())
   {
      cout << "Queue front is " << q.front() << endl;
      q.pop();
      cout << "Popped front element" << endl;
   }

   try {q.pop();}
   catch (queueEmpty message)
   {
      cout << "Last pop failed " << endl;
      message.outputMessage();
   }

   // create a wraparound queue and do array doubling
   arrayQueue<int> r(4);
   r.push(1);
   r.push(2);
   r.push(3);
   r.pop();
   r.pop();
   r.push(4);
   r.push(5);
   r.push(6);
   r.push(7);

   cout << "Queue should be 34567, front to rear" << endl;

   // test empty and size
   if (r.empty())
      cout << "The queue is empty" << endl;
   else
      cout << "The queue is not empty" << endl;

   cout << "The queue size is " << r.size() << endl;

   while (!r.empty())
   {
      cout << "Queue front is " << r.front() << endl;
      r.pop();
      cout << "Popped front element" << endl;
   }

   return 0;
}

问题:

  1. 当copy原队列至新队列时,start与2的关系,是什么意义?
int start = (theFront + 1) % arrayLength;
if (start < 2)
    // no wrap around
    copy(queue + start, queue + start + arrayLength - 1, newQueue);
 else
 {  // queue wraps around
    copy(queue + start, queue + arrayLength, newQueue);
    copy(queue, queue + theBack + 1, newQueue + arrayLength - start);
 }
  1. 当新队列拷贝完成后,没有看到老队列的delete操作。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值