Deques, or double-ended queues, are sequence containers that provide efficient insertion and deletion at both the beginning and end ( Cormen et al., 2009 ). Much like vectors, deques enable access to elements by index position. However, they differ in a few key aspects. First, while vectors guarantee contiguous storage allocation for their elements, deques may allocate storage non-contiguously for efficiency (Josuttis, 2012). Second, deques' dynamic size expansion and contraction is optimized for operating on both ends, not just one end like vectors. Josuttis (2012) notes that it makes deques more efficient than vectors for add/remove at the front. Finally, by supporting constant time O(1) insertion and deletion at both ends, deques simultaneously enable first-in-first-out queuing and last-in-first-out stacking semantics within the same data structure (Cormen et al., 2009). This dual-ended nature makes deques versatile for algorithms requiring access from both directions.
The deque::assign method assigns new contents to a deque, replacing its existing elements. Here is an explanation of it:
The assign function allows replacing all the elements of a deque with new elements specified by its parameters. It completely erases any existing contents of the deque and fills it with copies of the provided element value instead.
The syntax is:
deque_name.assign(number, value)
Where:
Number: Number of element copies to insert into the deque. Determines the new size.
value: The value assigned to each of these number elements. All elements will be copies of value.
deque::assign
Some key points about assign :
- It clears the original deque before assigning.
- The size of the deque changes to 'number' .
- Any iterators or pointers, except those pointing to the newly assigned elements, may get invalidated.
- It can cause lengtherror or badalloc exceptions if the number is too large or memory allocation fails.
- The assign function is useful to replace the contents of a deque entirely in one go. Reallocating space for new elements allows reusing an existing deque flexibly instead of creating a new one.
C++ Program using deque::assign.
Let us take an example to illustrate the use of deque::assign in C++.
#include <iostream>
#include <deque>
int main() {
// Creating a deque
std::deque<int> myDeque;
// Assigning values using assign()
myDeque.assign({1, 2, 3, 4, 5});
// Displaying the elements of the deque
std::cout << "Elements of the deque after assign: ";
for (const auto& element : myDeque) {
std::cout << element << " ";
}
std::cout << std::endl;
// Assigning a range of values
myDeque.assign(3, 100); // Assigning three elements with value 100
// Displaying the elements of the deque
std::cout << "Elements of the deque after second assign: ";
for (const auto& element : myDeque) {
std::cout << element << " ";
}
std::cout << std::endl;
return 0;
}
Output:
Elements of the deque after assign: 1 2 3 4 5
Elements of the deque after second assign: 100 100 100
Complexities:
Time Complexity:
- The time complexity of std::deque::assign is linear in the size of the provided range or the number of elements specified.
- The time complexity in both circumstances is O(N) , where N is the number of allocated items.
Space Complexity:
- The space complexity is O(N) , where N is the number of assigned elements.
- The space required is proportional to the number of elements assigned or the provided range's size.
deque::empty
The deque::empty method is used to check whether a deque container is empty.
Here are some key points about deque::empty :
Prototype: bool empty() const;
- It returns a bool value - actual if the deque is empty, false if it contains elements.
- It is a constant operation running in O(1) time complexity. Checking if empty is fast.
Usage:
std::deque<int> mydeque;
if(mydeque.empty()) {
cout << "Deque is empty!\n";
} else {
cout << "Deque contains elements.\n";
}
Checking emptiness with empty before accessing elements prevents unwanted segmentation faults and errors.
It is more efficient than comparing deque.size to 0 . It does not traverse and count; just checks an internal flag.
It works for any kind of deque containers, like deques of built-in types, custom objects, etc.
In summary, deque::empty is used to efficiently check whether a deque is empty before accessing elements, preventing potential errors.
Syntax:
It has the following syntax:
deque.assign(count, value)
Parameters:
count - Number of elements to insert.
value - The value to assign to the elements.
Header file:
#include <deque>
Iteration validity:
Iterators and references to the deque elements remain valid, except those pointing to the "replaced-by-assign" elements.
Exceptions:
It throws std::lengtherror and std::badalloc exceptions:
std::lengtherror - if count > maxsize
std::bad_alloc - if memory allocation fails
To explain further, the deque::assign function replaces the current deque content with count copies of the value parameter. All previous elements of the deque are removed in the process.
Any iterators or element references pointing to the replaced elements are invalidated, while the rest remain valid even after the assign operation. Reusing an existing deque is useful by completely replacing its contents.
C++ Program using deque::empty:
Let us take an example to illustrate the use of deque::empty in C++.
#include <iostream>
#include <deque>
int main() {
// Creating a deque
std::deque<int> myDeque;
// Checking if the deque is empty
if (myDeque.empty()) {
std::cout << "Deque is empty." << std::endl;
} else {
std::cout << "Deque is not empty." << std::endl;
}
// Adding elements to the deque
myDeque.push_back(42);
// Checking if the deque is empty after adding an element
if (myDeque.empty()) {
std::cout << "Deque is empty." << std::endl;
} else {
std::cout << "Deque is not empty." << std::endl;
}
return 0;
}
Output:
Deque is empty.
Deque is not empty.
Complexities:
Time Complexity:
- The time complexity of std::deque::empty is O(1).
- Checking whether the deque is empty is a constant-time operation.
Space Complexity:
- The space complexity is O(1) .
- The function does not require additional space proportional to the deque's size; it only returns a boolean result.
Differences between deque::assign and deque::empty
Here is a comparison of the key differences between deque::assign and deque::empty in a table form:
| Feature | deque::assign() | deque::empty() |
|---|---|---|
| Purpose | It assigns new elements by replacing existing ones. | Checks if deque container is empty |
| Parameters | (count, value) | None |
| Returns | Nothing (void) | bool |
| Time Complexity | Linear O(n) | Constant O(1) |
| Effects on Deque | Erases original contents, resizes deque | None, only checks |
| Iterator Validity | Invalidates iterators to replaced elements | No effect |
| Exceptions | May throw lengtherror, badalloc | None |
| Usage | Replaces deque contents fully | Check emptiness before access |
In summary, the key differences are:
- assign replaces the entire deque by assigning new elements.
- empty simply checks the current emptiness.
- assign clears deque first while empty does not modify
- assign causes reallocation, empty just checks a flag
So assign completely changes the deque, while empty lets you check the current state without any modification.