---
# System prepended metadata

title: 'Week 1: Dynamic Array; Deque; Sorting; C++ Specifics'

---

# Week 1: Array; Sorting; C++ Specifics

[ToC]

## Declare large arrays globally instead of locally

- This is **bad**:

    ```cpp=
  
    void some_func() {
	    ...
	    int b[200000]; // array local to `some_func`, may fail allocation due to large size
	    ...
	}

	int main() {
	    ...
	    int a[100000]; // array local to `main`, may fail allocation due to large size
	    ...
	    some_func();
	    ...
	}
    ```

- This is **good**:
	```cpp=
	int a[100000], b[200000]; // global now; allocation won't fail
	
    void some_func() {
        ...
    }
	
    int main() {
        ...
        some_func();
        ...
    }
    ```

- The reason is not important for us, but *if you're curious*: A local data uses the stack allocation strategy which allows for a limited amount of data to be allocated. On the other hand, a global data is allocated statically on a separate data segment where the only limit is the available size of the RAM.

## `vector`: Dynamic array in C++ STL

- An array that can grow/shrink at the back efficiently at runtime.
- Will be your most often used data sructure.

### How to use

- Declare: 
    ```cpp=
    // type of the contained element goes inside `<` and `>`
    vector<int> a;
    vector<double> b;
    vector<string> c;
    ```
- Declare with pre-allocated size and fill-value:

    ```cpp=
    vector<int> a1(1000); // 1000 ints, all set to 0 (the default int value)
    vector<string> b1(1000); // 1000 strings, all set to "" (the default string value)
    vector<int> a2(1000, -1); // 1000 ints, all set to -1
    vector<string> b2(1000, "xyz"); // 1000 strings, all set to "xyz"
    ```
    
- Query size/length in $O(1)$ time:

    ```cpp=
    a.size();
    a.empty(); // returns `a.size() == 0`
    ```

- Index-based access to elements in $O(1)$ time, like in arrays:

    ```cpp=
    cout << "first element: " << a[0] << "\n";
    cout << "last element: " << a[a.size() - 1] << "\n"; 
    
    ...
    
    cout << "all elements: ";
    for (int i = 0; i < a.size(); i++) {
        cout << a[i] << " ";
    }
    cout << "\n";

    a.front(); // convenience function to access first element without index
    a.back(); // convenience function to access last element without index
    ```

- **[Most important]** Add/remove elements **at the back** in $O(1)+$ (i.e. amortized constant) time:

    ```cpp=
    vector<int> a;
    for (int i = 0; i < 10; i++) {
        a.push_back(i + 1);
        cout << "added: " << a.back() << "\n";
    }
    for (int i = 0; i < 10; i++) {
        cout << "removing: " << a.back() << "\n";
        a.pop_back();
    }

    ```

### When and why to use

- You don't know the number of elements beforehand

## `deque`: Dynamic array, but for both ends

- Exactly like `vector`, but can also add/remove **at the front**:


    ```cpp=
    deque<int> a;
    for (int i = 0; i < 10; i++) {
        if (i % 2 == 0) {
            a.push_front(i);
        } else {
            a.push_back(i);
        }
    }
    for (int i = 0; i < 10; i++) {
        cout << a[i] << " ";
    }
    cout << "\n";
    ```


