Структуры данных (14 сентября 2016)
- С++
- Выделение, освобождение памяти: int *a = new int[n];, delete[] a;
- Неинициализированные переменные: -Wall, -Wextra, -Wshadow
- RangeCheckError: int a[10], x; a[10]; // иногда undefined behavior
- RangeCheckError fix:
vector<int> a; a.at(10); #define _GLIBCXX_DEBUG
- Структуры:
struct T { int a, b; }; T x; x.a;
- Указатели:
int *a = &b;
- Неасимптотические оптимизации
- cmath: sqrt, sin, cos, atan, ...
- Вызов функции (если оптимизатор не уберёт его). Пример с рекурсией.
- Ввод, вывод (scanf/printf, cin/cout)
- Операции с памятью: new, delete. Работают не за O(1).
- Случайный, а не последовательный доступ к памяти. Пример с проходом по матрице.
- Деление и взятие по модулю:
a /= b; a %= b;
. Пример с (a+b)%m.
- Простейшие структуры данных
- Сумма на отрезке. Частичные суммы.
- Массив фиксированного размера
- int a[n];
- Интерфейс: get(i), set(i,x) − O(1)
- Минусы: удаление и добавление в середину за O(n), поиск за O(n)
- Двусвязный списокк
struct node { node *l, *r; int data; };
struct list { int length; node *head, *tail; }; // пустой список: head = tail = 0
- Интерфейс:
add_front, add_back, del_front, del_back, add_after, del_node
за O(1)
- Добавим ссылки внутрь:
node* link[]; link[i]
− node добавленный i-й операцией, тогда появляется del(i) за O(1)
- Поиск за O(n), обращение к i-му элементу за O(min(i, n-i))
- Пишем код поиска x.
- Односвязный список
- struct node { node *next; int data; }; node *head = 0;
- Версия на массиве: struct node { int data, next; } a[n]; int head = -1;
- Пишем код добавления в начало.
− Перерыв −
- Расширяющийся массив (вектор)
- int size, an, a[size];
- get(i), set(i, x), pop_back() − O(1)
- push_back() − O(1) в среднем, доказательство
- Стек, очередь, дек
- Стек :
add_back = push, del_back = pop
за O(1), stack<int>
- Очередь :
add_front = push, del_back = pop
за O(1), queue<int>
- Дек :
add_front, add_back, del_front, del_back
за O(1), deque<int>
- Реализация на двусвязном списке
- Реализация очереди, дека на динамическом массиве
- Сравнение двусвязного списка и очереди.
- Очередь и стек с минимумом
- Стек с минимумом: частичные минимумы
- Очередь с минимумом через два стека:
Q = <S, S>
, push = O(1), pop = O(1) + reverse iff need
- Время работы: определяем амортизированное время. Пример: вектор.