std::vector

std::vector is a sequence container provided by the Standard Template Library (STL) that dynamically grows in size to accommodate elements as needed.

It stores elements in a contiguous memory block, providing constant-time access to elements using indexing.

std::vector is one of the most widely used containers in C++ due to its versatility and performance characteristics.

Creating a std::vector:


To use std::vector, you need to include the <vector> header.

#include <iostream>
#include <vector>

int main() {
    // Create an empty vector of integers
    std::vector<int> myVector;

    // Create a vector with initial size and default value
    std::vector<int> initializedVector(5, 100); // A vector of size 5, with each element initialized to 100

    // Create a vector and initialize using initializer list
    std::vector<int> vectorWithInitializer = {10, 20, 30, 40, 50};

    return 0;
}

Important Functions of std::vector:

push_back(value):

  • Adds an element to the end of the vector.
  • Time Complexity: Amortized constant time (O(1)).
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector;

    myVector.push_back(10);
    myVector.push_back(20);
    myVector.push_back(30);

    return 0;
}

pop_back():

  • Removes the last element from the vector.
  • Time Complexity: Constant time (O(1)).
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector = {10, 20, 30};

    myVector.pop_back(); // After this, myVector contains {10, 20}

    return 0;
}

size():

  • Returns the number of elements in the vector.
  • Time Complexity: Constant time (O(1)).
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector = {10, 20, 30};

    std::cout << "Size of the vector: " << myVector.size() << std::endl; // Output: 3

    return 0;
}

empty():

  • Checks if the vector is empty.
  • Time Complexity: Constant time (O(1)).
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector;

    if (myVector.empty()) {
        std::cout << "Vector is empty." << std::endl;
    } else {
        std::cout << "Vector is not empty." << std::endl;
    }

    return 0;
}

clear():

  • Removes all elements from the vector.
  • Time Complexity: Linear time (O(n)).
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector = {10, 20, 30};

    myVector.clear(); // After this, myVector is empty

    return 0;
}

resize(newSize, value):

Resizes the vector to the new size. If newSize is greater than the current size, new elements are added with value value. If newSize is smaller, elements are removed from the end.

  • Time Complexity: Linear time (O(n)), where n is the new size.
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector = {10, 20, 30};

    myVector.resize(5, 100); // After this, myVector contains {10, 20, 30, 100, 100}

    return 0;
}

reserve(newCapacity):

Sets the capacity of the vector to at least newCapacity. This can improve performance when you know the approximate size of the vector beforehand and want to avoid frequent reallocations.

  • Time Complexity: Linear time (O(n)), where n is the new capacity.
  • Space Complexity: Linear space (O(n)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector = {10, 20, 30};

    myVector.reserve(10); // The capacity of myVector is now at least 10

    return 0;
}

front():

Returns a reference to the first element in the vector.

  • Time Complexity: Constant time (O(1)).
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector = {10, 20, 30};

    int firstElement = myVector.front(); // firstElement = 10

    return 0;
}

back():

Returns a reference to the last element in the vector.

  • Time Complexity: Constant time (O(1)).
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector = {10, 20, 30};

    int lastElement = myVector.back(); // lastElement = 30

    return 0;
}

at(index):

Returns a reference to the element at the specified index, with bounds checking.

  • Time Complexity: Constant time (O(1)).
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector = {10, 20, 30};

    int element = myVector.at(1); // element = 20

    return 0;
}

operator[]:

Returns a reference to the element at the specified index, without bounds checking (be cautious with out-of-bounds access).

  • Time Complexity: Constant time (O(1)).
  • Space Complexity: Constant space (O(1)).
#include <iostream>
#include <vector>

int main() {
    std::vector<int> myVector = {10, 20, 30};

    int element = myVector[1]; // element = 20

    return 0;
}

Advantages of std::vector:

  1. Efficient access: std::vector provides constant-time access to elements using indexing.
  2. Dynamic resizing: It automatically resizes and manages memory when elements are added or removed.
  3. Contiguous memory: The elements are stored in a contiguous memory block, resulting in cache-friendly behavior and faster iteration.
  4. Versatility: It can be used for various data storage and manipulation tasks due to its dynamic nature.

Disadvantages of std::vector:

  1. Insertion and deletion: Adding or removing elements in the middle of the vector requires shifting elements, which can be inefficient for large vectors.
  2. Reallocation overhead: Resizing the vector may involve reallocation and copying of elements, leading to occasional performance penalties.

std::vector is a powerful and widely used container in C++. It is often the go-to choice for general-purpose data storage when the size of the container is not known in advance and you require efficient access to elements. However, for scenarios where frequent insertion and deletion in the middle of the container are expected, you may consider using other containers like std::list or std::deque that offer better performance for such operations.