Você está na página 1de 6

THE DEQUE

Through this article, you will learn about:


• the most basic information about the deque,
• three example programs,
• some additional information on some useful methods and properties,
• comparing dynamic data structures and reasons(“yes vs not”) to use the deque.

Now, in order to learn more about this subject, all is expected from you is the will to learn new things
and some love of programming.

WHAT IS THE DEQUE AND SOME BASIC PROPERTIES

In order to visualize the deque I would suggest you to imagine the deck of cards that are good for
adding the new cards at its top or bottom. It is possible to shuffle the cards, but adding cards in the
middle would take more time.

It is usual to distinguish two types of containers: the sequential and the associative.
The sequential will maintain the order of elements, but associative will not care about the order. One
representative example of sequential dynamic data structure is deque and one representative example of
associative structure could be set.
However, there are the adapters like a queue for example. This type of containers usually is
implemented as a modification of some other container. This will reduce actual performance in some
cases.

The deque has few interesting properties that come from it's structure:
• it is good for adding elements at its end or beginning,
• it is also good for removing elements at its end and beginning,
• it's elements could be accessed through iteration from beginning or from the end,
• it will perform well if we need to access element at certain position,
• it is not good for adding the elements in it's middle, however some programmers would use
swap in order to overcome that hurdle.

EXAMPLES

#1 In this example we will learn how to use basic methods for the deque.

CODE:

#include <iostream>
#include <deque>
using namespace std;

int
main( void )
{
deque < int > nDeque;

nDeque.push_back( 111 );
nDeque.push_back( 222 );
nDeque.puch_back( 333 );
//nDeque.pop_back();
nDeque.puch_back( 444 );

for( int index = 0; index < nDeque.size(); index++ )


cout<< nDeque[ index ]<<” , “;

return EXIT_SUCCESS;
}

In this code example, we have:


• declared our deque,
• pushed four elements to its back,
• and presented the elements of the deque.
As the expected output, you should see: 111, 222, 333, 444.

So, if you have fixed your code to produce the expected output, next thing to do is to uncomment that
only comment. Analyze the change in the output and learn from it.

The next change you could do is to return the comment and change all push_back's into push_front.
Then the expected output would be bit different: 444, 333, 222, 111.
Now change commented nDeque.pop_back() into nDeque.pop_front() and uncomment it. Analyze the
output and learn from it.

In order to summarize what we have learn:


• push_back adds the element at the end of the deque and pop_back will remove it,
• puch_front adds the element at the beginning of the deque and pop_front remove it,
• size tells the size of our dynamic data structure.

Beside this way of presenting the deque, we could use the iterators as well. That could be achieved with
this code:

for( deque<int>::iterator member = nDeque.begin();


member != nDeque.end();
cout<< *member <<endl, ++member );

Now, not much different from this, is usage of constant iterator, and if we have no desire to change the
content of our deque constant iterators are better option( cbegin and cend ).
If one wants to present the elements back word, there are: rbegin and rend.

#2 This example program is oriented more toward new style of C++: 11, 14 and 17.

CODE:

#include <iostream>
#include <deque>
#include <algorithm>

using namespace std;

int
main( void )
{
deque < int > iDek { 5, 6, 9, 1, 2, 7 };

sort( iDek.begin();
iDek.end();
[]( int left, int right ){ return ( left > right ); } );

for( auto aMember : iDek )


cout<< aMember<<” “;

return EXIT_SUCCESS;
}

In this example program, we have done few interesting things:


• In order to declare the deque and initiate it with some data, we have this option now.
• Then we sort our deque and in order to sort it, we have used lambda. This way, we will have
that implementation near our sight and it will be used in order to decide the order(ascending or
descending).
• And in order to print the elements from our deque, we use new feature that will shorten the
codding time.

The expected output would be: 1, 2, 5, 6, 7, 9.

Try to change “>” into “<” and analyze the change, as an additional exercise.

#3 In order to put some more restrictions on deque, we will see how we can wrap-up our deque with
class and use the containment. As we have previously mention, the containment is one of the
relationships among the classes.
CODE:

#include <iostream>
#include <deque>

using namespace std;

class FunkyDeque
{
private:
deque < int > nDeque;
public:
void
add_in_front( int n )
{ nDeque.push_front( n ); }

int
remove_from_back( void )
{
int n = nDeque[ nDeque.size() - 1 ];
nDeque.pop_back();
return n;
}

void
present_data( void )
{
for( int i = 0 ;
i < nDeque.size() ;
cout<<nDeque[i++]<<endl);
}
};

int
main( void )
{
FunckyDeque FD;

FD.add_in_front( 111 );
FD.add_in_front( 121 );
FD.add_in_front( 131 );
int n = FD.remove_from_back();
cout<< n << endl;

FD.add_in_front( 141 );

FD.present_elements();

return EXIT_SUCCESS;
}
In this example code, we have allowed elements to be pushed in the front of the deque and we have
also allowed removal from the back of the deque.
Additional method that is used, presents elements in the main function.

The expected output would be: 111, 141, 131, 121.

This time we have class FunckyDeque that contains usual deque. This type of relationship is called
containment, because class FunckyDeque “has a deque”.

As a exercise, try to upgrade class FunckyDeque with some additional methods.

SOME ADDITIONAL METHODS THAT COULD COME IN HANNDY

We, have mention few member functions of deque, but few might be interesting as well.
For example, we have a constructor and a destructor, as well as the operator of assign(=).

In order to position you self at certain location, beside having operator[] you have at. However, this
choice might be better.

To test if your container is empty we have public member function. Few interesting are max_size and
shrink_to_fit since C++11.

In order to modify the container we could use: clear, insert, erase, emplace, emplace_front, resize.

And there are few non-member functions, that are used like operators: ==, !=, <, <=, > and >=.

Now, in order to do some more exercise, I will describe one solution.


In one of our previous posts, we have analyzed insertion sort, which is adding elements into the array at
its end. This could easily be modified and applied with vectors.
However, the elements could be added in the front of the deque too. So, if the element is smaller than
the first one in the structure, instead of adding the element at it's end we could add it at the beginning of
the deque. One interesting fact is that you could place elements closer to the beginning or to the end,
according to the estimation where the element fits better.
Hope, that this additional exercise is not tough.

COMPARATIONS OF DIFFERENT DATA STRUCTUES

When programmer faces different problem, picking right data structure can be of essential importance.
The skill full programmer will chose right data structure that will outperform some other in practical
exploration.
This process of choosing proper data structure will result in better program performance and ease of
programming, mostly. However, some other issues might arise too.

So, in order to decide if we need the container that will fit into the category of sequential dynamic data
structures we need to access the structure at some indexed manner, on the other hand associative data
structures will perform better if the order of elements doesn't matter.

The most common choice, in the cases we need sequential data structure, is the vector. Aldo, if we
would like to add the elements into it, at its beginning or remove them from the beginning the deque
could be better choice. The inner structure of the deck might cause slower performance when program
is running.
The additions and removals of elements at the deque's beginning or end, are constant operations. In
another words, the size of the container will not influence this operations.

Você também pode gostar