
- •1. Основы теории сложности. Классы сложности np и p.
- •2. Сортировка и поиск . Проверка упорядоченности массива. Способы сортировки.
- •3.Обменная сортировка (метод "пузырька", шейкер-сортировка)
- •4. Сортировка разделением (быстрая сортировка). Распределяющая сортировка.
- •5. Сортировка подсчётом. Сортировка выбором (прямой выбор, линейный выбор, квадратичная )
- •7. Пирамидальная сортировка. Сортировка слиянием (однократное и циклическое)
- •8. Стек. Основные базисные операции для работы со стеком. Организация стека на основе массива и связного списка.
- •9. Очередь. Основные операции для работы с очередью
- •10. Очередь с приоритетом. Основные операции для работы с очередью с приоритетом.
- •11. Деки. Логическая структура дека.
- •12. Списки как динамические структуры данных. Виды линейных списков. Способы формирования односвязных списков. Оценка сложности.
- •13. Односвязный список. Включение элемента в начало списка. Удаление элемента из списка по заданному номеру.
- •14. Односвязный список. Включение элемента в конец списка. Слияние 2 списков.
- •15. Двухсвязный список. Удаление и вставка элемента в список.
- •16. Циклические списки. Просмотр циклического списка.
- •17. Мультисписки. Нелинейные разветвлённые списки.
- •18. Особенности программирования рекурсивных функций. Линейная рекурсия (пример).
- •19. Смешанная, ветвящаяся и бинарная рекурсия. (примеры)
- •20. Рекурсия и поисковые задачи. Результат функции рекурсивного поиска, возврат последовательности, правила разработки.
- •21. Рекурсия и поисковые задачи. Ханойские башни. Генераторы перестановок, сортировки, алгоритмы с матрицами и др.
- •22. Деревья как рекурсивные структуры данных. Основные определения и свойства. Логическое представление и изображение деревьев.
- •23. Бинарные деревья. Вставка элемента
- •24. Бинарные деревья. Удаление элемента
- •25. Бинарные деревья. Поиск . Алгоритм представления любого дерева и леса бинарными деревьями.
- •26. Способы обхода бинарного дерева: нисходящий, восходящий, смешанный.
- •28. Сбалансированные деревья. Показатель сбалансированности. Avl-деревья.
- •29.Виды балансировки деревьев. Балансировка через массив.
- •30. Красно-чёрные деревья.
- •31. Приложения деревьев.Дерево Хаффмана. (оставь здесь 10 шрифт!!!)
- •32. Бинарная куча. Проверка основного свойства кучи.
- •33. Бинарная куча. Определение родительской и дочерних вершин.
- •34. Бинарнаякуча. Алгоритм построения кучи из произвольного массива.
- •36. Бинарная куча. Добавление элемента.
- •39. Алгоритмы вычисления хэш-функции.
- •44. Задача поиска подстрок, простейший алгоритм.
- •47. Методы разработки алгоритмов. Метод декомпозиции, динамическое программирование
- •48. Методы разработки алгоритмов. Жадные алгоритмы, поиск с возвратом, локальный поиск.
15. Двухсвязный список. Удаление и вставка элемента в список.
Двусвязные списки дают возможность просмотра элементов в обоих направлениях и являются наиболее универсальными. Двусвязные списки используются для создания цепочек элементов, которые допускают частые операции включения, исключения, упорядочения, замены и пр. В односвязных и двусвязных списках последний элемент содержит указатель NULL для обозначения факта окончания последовательности. Аналогично первый элемент двусвязного списка содержит указатель NULL на предыдущий элемент. В этом случае работа с первым и последним элементом списка имеет свои особенности. В качестве альтернативы может быть предложен циклический список, у которого последний элемент ссылается на первый, а первый-на последний. Вставка. После ввода очередного числа с клавиатуры определяем его место в списке. Заметим, что при этом элемент может быть вставлен либо в начало списка, либо в конец его, либо в середину. Для того чтобы вставить в список элемент со значением 123 между двумя элементами, нужно найти эти элементы и запомнить их адреса (первый адрес – в переменной px, второй – в dх), после чего установить новые связи с элементом, в котором хранится значение 123.
Node *find(Node *const pbeg, int d){// Поиск элемента по ключу
Node *pv = pbeg ; while (pv){ if(pv->d == d)break; pv = pv->next;} return pv;}
Node *insert (Node *const pbeg, Node **pend, int key, int d)// Вставка элемента
{ if(Node *pkey = find(pbeg, key)) { Node *pv = new Node; pv->d = d;
pv->next = pkey->next;// установление связи нового узла с последующим
pv->prev = pkey;// установление связи нового узла с предыдущим
pkey->next = pv;// установление связи предыдущего узла с новым
if(pkey != *pend)(pv->next)->prev = pv;// установление связи последующего узла с новым
// Обновление указателя на конец списка; если узел вставляется в конец
else *pend = pv; return pv; } return 0; }
Удаление. В вашем списке должен быть как минимум указатель на начало списка. Если он есть, вы всегда сможете N раз перейти на следующий и таким образом добраться до элемента N. Затем переставить указатели (N-1) и (N+1) в обход N-го, а сам N-ый удалить (delete).
bool remove(Node **pbeg, Node **pend, int key)// Удаление элемента
{ if(Node *pkey = find(*pbeg, key)) { if (pkey == *pbeg)// проверяется,находится ли удаляемый элемент в начале списка { *pbeg = (*pbeg)->next;// если да,то надо скорректировать указатель pbeg на начало списка так, чтобы он указывал на следующий элемент в списке, адрес которого находится в поле next первого элемента (*pbeg)->prev =0;// обнуляется указатель на предыдущий элемент}
else if (pkey == *pend)// если удаляемый элемент находится в конце списка, требуется сместить указатель pend конца списка на предыдущий элемент, адрес которого можно получить из поля prev последнего элемента
{*pend = (*pend)->prev; (*pend)->next=0;// обнуляется указатель на следующий элемент } else // Если удаление происходит из середины списка, то нужно лишь обеспечить двустороннюю связь предыдущего и последующего элементов
{ (pkey->prev)->next = pkey->next; (pkey->next)->prev = pkey->prev; } delete pkey; return true; } return false; }