Деревья курс «Алгоритмы и структуры данных» Отделение Программной инженерии
Что такое дерево Связный неориентированный граф, не имеющий циклов Структура данных, позволяющая выполнять операции вставки, удаления, поиска элементов за нелинейное время
Применение деревьев каталоги книжных интернет- магазинов представление файловых систем алгоритмы сжатия файлов реализации компиляторов
Свойства дерева дерево состоит из совокупности узлов кореньтолько один узел не имеет предков: это корень дерева только одноголюбой другой узел имеет только одного предка из любого узла можно попасть в корень, постоянно двигаясь от узла к его предку
Свойства дерева листьяузлы, не имеющие потомков – листья высота дерева количество уровней в дереве,высота дерева – это количество уровней в дереве, включая корень (то есть количество узлов в самой длинной цепочке от корня до листа)
Типы деревьев дерево общего вида (количество дочерних узлов для каждого узла не ограничено) бинарное бинарное дерево (количество дочерних узлов для каждого узла равно двум)
Кучи это деревья, содержащие элементы либо в возрастающем, либо в убывающем порядке
Двоичные деревья поиска Содержат элементы в отсортированном порядке, благодаря чему легко осуществляется поиск по дереву Несбалансированное двоичное дерево поиска - это дерево, в котором листья находятся не на одном уровне. левоеправоеОно имеет левое и правое поддеревья, высота которых различается на несколько уровней
незавершенным Двоичное дерево поиска называется незавершенным, если один или несколько его узлов имеют один дочерний узел Двоичные деревья поиска
Использование деревьев в STL
рекурсию. Процедура поиска нужного значения представляет собой рекурсию. рекурсивный вызов В случае, если входной параметр (текущая вершина) не совпадает с искомым значением (искомой вершиной), происходит рекурсивный вызов процедуры с параметром - корнем соответствующего поддерева: либо большего, либо меньшего. Если такое поддерево не найдено, то искомое значение не содержится в дереве. Использование двоичных деревьев поиска
template const T* const BSTree ::search_helper(BSTNode *nodep, const T &x) { if (nodep == 0) { return NULL; } if (x == nodep->data) { return &(nodep->data); } if (x data) { return search_helper(nodep->left, x); } else { return search_helper(nodep->right, x); } Использование двоичных деревьев поиска
Контейнер «множество» хранит уникальные упорядоченные элементы. Добавление и удаление элементов, доступ к ним выполняется за логарифмическое время. Добавление отсортированных элементов не сократит время до линейного. Множества
Множества Объявление множества set s1; set s2; Добавление элементов в существующее множество for (int i = 0; i < 20; i++) { s1.insert(i); s2.insert(30 - i); }
Множества Реализация функции поиска во множестве: if (s1.find(10) != s1.end()) { cout << "s1 contains 10\n"; } Функция возвращает итератор найденного элемента (если элемент не найден, то возвращается итератор конца множества)
Карты Контейнер «карта» - это ассоциативная структура данных, которая хранит элементы по парам «ключ - значение». Структура называется ассоциативной, так как ставит в соответствие один элемент данных (ключ) другому элементу данных (значению). Ключ должен быть уникальным (то есть соответствовать только одному значению)
Карты Объявление карты, имеющей строковый тип ключа и значения map m1; Добавление элементов в карту m1.insert(pair ("apple", "a small red fruit")); m1.insert(pair ("orange", "a small orange fruit"));
Карты Другой способ добавления элементов в карту m1[“apple”] = “a small red fruit”; m1[“banana”] = “a long yellow fruit”; Доступ к элементам по ключу в карте: cout << m1[“apple”] << endl; cout << m1[“banana”] << endl; Реализация итератора для просмотра элементов: map ::iterator it = m1.begin(); for ( ; it != m1.end(); it++) { cout first second << endl; }
Очереди приоритета Очереди приоритета похожи по поведению на обычные очереди. Очередь приоритета предоставляет доступ только к элементу с высшим приоритетом. Определение относительного приоритета элементов осуществляется при помощи оператора сравнения (<)
Очереди приоритета priority_queue pq; pq.push(1); pq.push(4); pq.push(2); cout << pq.top() << endl; // outputs '4' pq.pop(); cout << pq.top() << endl; // outputs '2' pq.pop(); cout << pq.top() << endl; // outputs '1' В некоторых типах (например, int) операция сравнения определена по умолчанию Если операция сравнения не определена (например, для типа string), то программист определяет ее самостоятельно