Efficieny of stl vector and queue - c++

I want to implement a program using either vector or queue data structure. The function requires frequently pushing and popping some elements (e.g. 8 elements) from the data structure to process these elements, and finally the data structure will be empty. The processing order doesn't matter so both vector and queue are ok. I want to know which one has higher efficiency if I need to frequently push and pop from it. Thank you.

std::queue isn't a container. It is a container adapter. By default, it adapts std::deque.
The function requires frequently pushing and popping some elements ... The processing order doesn't matter
This seems to imply that you can pop from the same end where you push (LIFO). In that case, another container adaptor would be appropriate: std::stack. It also adapts std::deque by default. There is no difference in efficiency of std::vector and the efficiency of std::stack that adapts std::vector. There can be a difference in using std::deque depending on the details of how you use it.

Related

Why is not possible to have a queue implemented as a vector?

What are the drawbacks of using a std::vector for simulating a queue? I am naively thinking that push_back is used for push and for pop one just stores the position of the first element and increments it. Why does not std::queue allow a std::vector implementation like this in principle (I know the reason is it has no push_front method, but maybe there is something deeper that makes it slow this way)? Thank you for helping.
Why does not std::queue allow a std::vector implementation like this
std::queue is a simple container adapter. It works by delegating pop function to the pop_front function of the underlying container. Vector has no pop front operation, so std::queue cannot adapt it.
but maybe there is something deeper that makes it slow this way
Pushing and popping from the front of the vector is slow because it has to shift all elements which has linear cost. This is why vector doesn't provide pop_front.
stores the position of the first element and increments it.
It's possible to implement a container that does store the position of first element within a buffer, but vector is not an implementation of such container. Storing that position has an overhead that vector doesn't need to pay, and so it doesn't.

Is there a function to add to the bottom of a c++ stack?

I could always use an array and write an algorithm for pushing items to the top but a stack would probably be more efficient and simpler to use later. I've searched for this function and couldn't find one.
Use a std::deque, which provides both std::deque::push_back and std::deque::push_front methods for pushing elements to the "top" and "bottom" of the data structure, respectively, in constant time.
std::stack is a container adapter, not a container itself. That means it simply enforces a stack interface (which by definition only offers push and pop to the top of the stack) over the top of a user specified underlying container that provides push_back(), pop_back() and back() functions. By default std::stack uses std::deque as its underlying container but std::vector and std::list are standard containers that also meet the requirements (and std::vector is probably a better choice in most cases).
If you want to be able to push to the other end of the stack then just directly use a container that supports that efficiently - std::deque is likely your best choice.
std::stack is a FILO data container, full stop. You can add to the back and then you can remove from the back. If you need to do anything else, then you need to use a container that isn't std::stack.
You seem to be using wrong container for what you want to achieve. deque seems to be a better fit.

How do I efficiently copy an entire queue to a vector/an array in C++?

How do I efficiently copy an entire queue to a vector/an array in C++?
say I have a std::queue and at some point I want to copy it to a vector/an array and then sort it.
Thanks for everyone's answers.
What I really want to do is to create a window with a fix length and at some point i need to copy all the elements inside this window and sort them. the window is moving and there are new data coming in through another interface so i want to use queue. is there any better implementations?
You wrote:
What I really want to do is to create a window with a fix length and at some point i need to copy all the elements inside this window and sort them. the window is moving and there are new data coming in through another interface so i want to use queue.
I suggest to take a step back, and reconsider whether you really want to use a queue. I suppose you want it because you
want to expose a minimal interface to the other component which adds data to the queue.
efficient addition/removal of elements at the front/back (to implement the 'fixed width window' concept)
an efficient way to access the data visible in the window sorted
Unfortunately, std::queue isn't very suitable for (3). Hence, I'd suggest to look for something which addresses (2) and (3), and then consider writing a wrapper of some sort (maybe a plain function which just adds an element to the queue will do?) to implement (1).
For instance, I'd consider using a plain std::deque. It can add/remove elements from the beginning/end of the queue in constant time. It's also very easy to get a sorted view on the window, e.g. if copying the elements of the queue is cheap you could use std::sort like:
std::vector<Elem> sortedView( queue.begin(), queue.end() );
std::sort( sortedView.begin(), sortedView.end() );
...you could of course also do something more clever by not copying the data but rather creating a vector of iterators into the queue, or by using a different sorting algorithm like partial_sort.
If you just want to keep a sorted queue, take a look at priority_queue.
Honestly, the best option is to use the right STL data structure from the start. If you will want to sort the data, a std::queue is not the right data structure.
Consider using a map (or perhaps a hash map). Typical implementations of maps actually build the map sorted, with lookups being performed in O(ln) time. You can still iterate sequentially through a map too, if you really want to.
The only way to access std::queue elements is using a combination of front, back, push, pop since std::queue has no iterators. (In order to be able to use iterators, you should use the underlying container (e.g. std::deque) directly, instead of std::queue.
Since you want to make a copy (presumably leaving the elements in the queue as they were), you can push elements back into the queue after you pop them.
Also, since you know the size of the queue, you can use vector::reserve to prevent expensive memory reallocations triggered by vector::push_back.
So
std::vector<int> V;
std::queue<int> Q;
V.reserve(Q.size());
for(size_t numPos = 0; numPops < Q.size(); ++numPops) {
V.push_back(Q.front());
Q.pop();
Q.push(V.back());
}
std::sort(V.begin(), V.end());

Advantages of Setting priority_queue Container

With the stl priority_queue you can set the underlying container, such as a vector. What are some of the advantages of specifying a container for the stl priority_queue?
Setting the underlying container makes it possible to separate out two logically separate concerns:
How do you store the actual elements that make up the priority queue (the container), and
How do you organize those elements to efficiently implement a priority queue (the priority_queue adapter class).
As an example, the standard implementation of vector is not required to shrink itself down when its capacity is vastly greater than its actual size. This means that if you have a priority queue backed by a vector, you might end up wasting memory if you enqueue a lot of elements and then dequeue all of them, since the vector will keep its old capacity. If, on the other hand, you implement your own shrinking_vector class that does actually decrease its capacity when needed, you can get all the benefits of the priority_queue interface while having the storage be used more efficiently.
Another possible example - you might want to change the allocator being used so that the elements of the priority queue are allocated from a special pool of resources. You can do this by just setting the container type of the priority_queue to be a vector with a custom allocator.
One more thought - suppose that you are storing a priority_queue of very large objects whose copy time is very great. In that case, the fact that the vector dynamically resizes itself and copies its old elements (or at least, in a C++03 compiler) might be something you're not willing to pay for. You could thus switch to some other type, perhaps a deque, that makes an effort not to copy elements when resizing and could realize some big performance wins.
Hope this helps!
The priority_queue class is an example of the adapter pattern. It provides a way of providing the services of a priority queue over an existing data set. As an adapter, it actually requires an underlying container. By default, it specifies a vector. (from here).
In terms of the advantages, it's simply a more flexible. The priority_queue uses the following methods of the backing store and requires it to support random access iterators.
front
push_back
pop_back
By providing it as an adapter, you can control the performance characteristics by supplying a different implementation.
Two examples that implement this in STL are vector and deque. These both have different performance characteristics. For example, a vector typically is continguous in memory, whereas a deque typically isn't. The push_back operation in a vector is only amortized constant time (it might have to reallocate the vector), whereas for the deque it's specified in constant time.

c++ deque vs queue vs stack

Queue and Stack are a structures widely mentioned. However, in C++, for queue you can do it in two ways:
#include <queue>
#include <deque>
but for stack you can only do it like this
#include <stack>
My question is, what's the difference between queue and deque, why two structures proposed? For stack, any other structure could be included?
Moron/Aryabhatta is correct, but a little more detail may be helpful.
Queue and stack are higher level containers than deque, vector, or list. By this, I mean that you can build a queue or stack out of the lower level containers.
For example:
std::stack<int, std::deque<int> > s;
std::queue<double, std::list<double> > q;
Will build a stack of ints using a deque as the underlying container and a queue of doubles using a list as the underlying container.
You can think of s as a restricted deque and q as a restricted list.
All that is necessary is that the lower level container implements the methods needed by the higher level container. These are back(), push_back(), and pop_back() for stack and front(), back(), push_back(), and pop_front() for queue.
See stack and queue for more detail.
With respect to the deque, it is much more than a queue where you can insert at both ends. In particular, it has the random access operator[]. This makes it more like a vector, but a vector where you can insert and delete at the beginning with push_front() and pop_front().
See deque for detail.
Queue: you can insert only in one end and remove from the other.
Deque: you can insert and remove from both ends.
So using a Deque, you can model a Queue as well as a Stack.
Hint:
Deque is short for "Double ended queue".
deque is a container template. It satisfies the requirements for a sequence with random-access iterators, much like a vector.
queue is not a container at all, it is an adaptor. It contains a container and provides a different, more specific interface. Use queue when you want to remember (or remind) to avoid operations besides push[_back] and pop[_front], front and back, size and empty. You can't look at elements inside the queue besides the first and last, at all!
In the C++ library, both std::stack and std::queue are implemented as container adapters. That means they provide the interface of a stack or a queue respectively, but neither is really a container in itself. Instead, they use some other container (e.g. std::deque or std::list to actually store the data), and the std::stack class just has a tiny bit of code to translate push and pop to push_back and pop_back (and std::queue does roughly the same, but using push_back and pop_front).
A deque is a double-ended queue, which allows easy insertion/removal from either end. Queues only allow insertion in one end and retrieval from the other.
deque supports insert/pop from back & front
queue only supports insert to the back, and pop from the front. You know, a FIFO (first in first out).
A deque is double-ended. A queue isn't.
Priority queue dequeue happens according to some ordering (priority) comparison not the enqueue order.
For instance you might store timed events in one where you want to pull out the soonest event first and query for its scheduled time so you can sleep until that point in time.
Priority queues are often implemented using heaps.
by Mike Anderson here:
https://www.quora.com/What-is-the-difference-between-a-priority-queue-and-a-queue
In deque(double-ended queue) The element can be inserted from the back and removed from the rear(like in stack), but queue only allows removal from the front.