0
unsigned mySize;       // number of items I contain
unsigned myCapacity;   // how many items I can store
unsigned myFirst;      // index of oldest item (if any)
unsigned myLast;       // index of next available spot for append (if any)
Item*    myArray;      // dynamic array of items

I am creating a dynamic array-based queue class and need to make a method that changes the number of items that a queue can hold. I need "myLast" to remain accurate after the capacity has changed, especially on a queue that has already had items dequeued from the front.

void ArrayQueue<Item>::setCapacity(unsigned cap) {
if (cap < getSize() || cap == 0){
    throw QueueException("setCapacity()", "New capacity must be greater than size");
} else {
    Item * nq = new Item[cap];
    for (unsigned i = 0; i < cap; i++){
        nq[i] = myArray[i];
    }
    delete [] myArray;
    myArray = nq;
    myCapacity = cap;
//what do I put here to make myFirst and myLast be correct for the new capcacity?
       }
    }

Can anyone explain how to do this?

user3020033
  • 15
  • 2
  • 10
  • 6
    Isn't the whole point of a queue that it grows in constant time and can grow indefinitely? Most queue implementations are just linked lists – cppguy Apr 23 '14 at 17:34
  • 1
    @cppguy A linked list is not a very efficient implementation for a queue. – ooga Apr 23 '14 at 17:37
  • shouldn't myLast be updated only during insertion and deletion? – Bruno Ferreira Apr 23 '14 at 17:44
  • ^ yeah... Why would they be incorrect at this point? They're indices into the array, not pointers to elements. – Alex Reinking Apr 23 '14 at 17:52
  • I must be doing something wrong because the method does not pass tests I give it for the correct item at myLast. Sorry, I'm pretty new with the use of queues. – user3020033 Apr 23 '14 at 18:06
  • @ooga care to elaborate on `A linked list is not a very efficient implementation for a queue` ?? No bulk copies/moves... – Massa Apr 23 '14 at 18:15
  • 1
    @Massa Not really, no. Note, however, that the STL `queue` container adaptor class uses a `deque` as it's underlying container, not a `list`. For a `deque`, "typical implementations use a sequence of individually allocated fixed-size arrays". – ooga Apr 23 '14 at 18:20
  • @ooga is correct regarding deque. `[000XXX][XXXXXX][XXXXXX][XXXX00]` would be such a layout for typical deque pages (pagesize=6,filled=`X`, empty=`0`). The front page insertion point moves *backwards* for front-pushes, the tail page insertion point moves *forwards* during back-pushes. At least most of the ones I've dissected do it that way, and it is *very* efficient for genuine deque-activity. – WhozCraig Apr 23 '14 at 20:06
  • Regardless of implementing using a list or deque (which is really an issue around avoiding fragmentation vs insertion complexity which doesn't matter because queue's are only modified on their head and tail) A fixed size queue necessitates bulk copies/moves for resizing – cppguy Apr 23 '14 at 21:25

2 Answers2

0

Nothing-- neither myFirst nor myLast change with what you have-- unless you're using a circular queue (and I bet you are), in which case, you can't just copy the original array over the new array. If you just copy the old array over the new one, any entries that wrapped around will end up out of place. You need to handle the possibility that it has wrapped around.

And you have a problem with your for loop:

for (unsigned i = 0; i < cap; i++){
    nq[i] = myArray[i];
}

It's going to run off the end of myArray if cap is greater than myCapacity (e.g. the size of myArray).

Rob K
  • 8,757
  • 2
  • 32
  • 36
0

You can change your container in queue if you wish..

 std::queue<int,std::list<int>> myQueue

like this...

Grayowl
  • 77
  • 3
  • 12