- •16. Обход n-арного дерева. Алгоритмы обхода n-арного дерева.
- •17.Бинарные деревья – основные определения, свойства и теоремы.
- •18,19.Не рекурсивные алгоритмы обхода бинарного дерева.
- •20.Поиск в упорядоченных таблицах. Последовательный поиск в массиве.
- •21.Поиск в упорядоченных таблицах. Двоичный поиск в массиве. Фибоначчиев поиск. Интерполяционный поиск.
- •22. Поиск в линейном списке.
- •23.Двоичное дерево поиска. Свойства. Основные операции.
- •Iterative_Tree_Search(t,k).
- •24. Добавление элемента в двоичном дереве поиска.
- •25. Удаление элемента в двоичном дереве поиска.
- •26. Абстрактная таблица. Основные операции. Способ реализации.
- •27. Авл – деревья. Свойства. Вращение. Высота авл-дерева (теорема) Определение и свойства авл-дерева
- •Авл - дерево
- •Повороты при балансировке
- •Алгоритм на псевдокоде
- •Алгоритм на псевдокоде
- •29. Удаление вершины в авл – дереве.
- •Алгоритм на псевдокоде
- •30. Красно – черные деревья. Свойства. Вращение. Высота красно – черного дерева.
- •Повороты
- •Операции поворота в бинарном дереве поиска
- •31. Добавление вершины в красно – черном дереве.
- •32. Удаление вершины в красно – черном дереве.
- •33. 2-3 Деревья. Основные свойства. Высота 2-3 дерева.
- •34 Обход 2-3 дерева.
- •35 Добавление элемента в 2 – 3 дерево.
- •36 Удаление элемента в 2 – 3 дереве.
- •37 2 – 3 – 4 Деревья. Основные свойства. Высота 2 – 3 – 4 дерева.
- •38 Добавление элемента в 2 – 3 – 4 дерево.
- •39. Стратегии внутренней сортировки.
- •40. Турнирная сортировка.
- •41. Пирамидальная сортировка.
- •42. Вставка с убывающим шагом.
- •43. Быстрая сортировка.
- •44. Быстрая двоичная сортировка.
- •45. Цифровая сортировка.
- •46. Карманная (блочная) сортировка.
- •47. Сортировка подсчетом
- •48. Сортировка слиянием. Рекурсивный алгоритм
- •49. Нижняя граница вычислительной сложности алгоритмов сортировки.
- •50. Поиск в глубину в графе. Рекурсивный алгоритм.
- •51. Поиск в ширину в графе. Не рекурсивный алгоритм.
- •52. Топологическая сортировка. Алгоритм топологической сортировки.
- •58. Стягивающие деревья. Нахождение стягивающего дерева методом поиска в ширину
- •59. Стягивающие деревья. Нахождение стягивающего дерева методом поиска в глубину.
- •60.Минимальные покрывающие деревья. Алгоритм Прима
- •61.Минимальные покрывающие деревья. Алгоритм Крускала.
- •62. Нахождение кратчайших путей в графе. Алгоритм Форда – Беллмана
- •63 Поиск кратчайших путей в графе. Алгоритм Дэйкстры.
- •64 Пути в бесконтурном графе.
- •65 Алгоритм Флойда поиска кратчайших путей между всеми парами вершин
- •66. Открытое хеширование.
- •67. Хеш-функции (ключи как натуральные числа, деление с остатком, умножение).
- •68. Закрытое хеширование. (Линейная последовательность проб. Квадратичная последовательность проб. Двойное хеширование).
- •69 Алгоритм Кнута-Морриса-Пратта.
- •70 Поиск подстрок. Алгоритм Бойера-Мура.
- •71. Поиск подстрок. Алгоритм Рабина-Карпа
- •72 Равномерный и неравномерный код. Префиксное кодирование.
- •73. Алгоритм Шеннона – Фано
- •74. Сжатие информации. Метод Хаффмана.
- •75. Исчерпывающий перебор. Задачи коммивояжера. Задача о назначениях.
- •77. Метод ветвей и границ. Задача о назначениях. Задача о рюкзаке. Задача коммивояжера.
- •Постановка задачи коммивояжера
- •Алгоритм решения задачи коммивояжера Жадный алгоритм
- •Полный перебор
- •78. Динамическое программирование. Восходящее и нисходящее динамическое программирование
- •79.Задача определения наиболее длинной общей подпоследовательности.
- •80. Перемножение последовательности матриц.
52. Топологическая сортировка. Алгоритм топологической сортировки.
Топологическая сортировка ориентированного ациклического графа G=(V,E) представляет собой такое линейное упорядочение всех его вершин, что если граф G содержит ребро (u,v), то u при таком упорядочении располагается до v (если граф не является ацикличным, такая сортировка невозможна). Топологическую сортировку графа можно рассматривать как такое упорядочение его вершин вдоль горизонтальной линии, что все ребра направлены слева направо.
Мы можем выполнить топологическую сортировку за время θ(V+E), поскольку поиск в глубину выполняется именно за это время, а вставка каждой из |V| вершин в начало связного списка занимает время О.
Алгоритм TopologSort(G)
for each vV do
num [v] ←0
lable [v] ←0
end for
j←|V|+1
i←0
for each vV do
if num [v]=0 then TOPSORT(V)
end for
TOPSORT(V)
i←i+1
num [i] ←i
for each wV, смежные с v do
if num[w]=0 then TOPSORT(W)
else if lable [w] to then
printf “граф содержит цикл”
end if
end if
Двусвязность. Алгоритм определения двусвязности графа.
Если граф не одержит точек разделения, то он называется двусвязным или неразделимым. Максимальный подграф называется двусвязной компонентой или блоком. Для определения точек сочленения – последовательно убирать точки и анализировать, распадается ли граф на несвязные компоненты.
Алгоритм BICONNECTIVITY(G)
num ←0, stack ←Ø
for each v V do Num[v] ←0, L[v] ←0
for each v V do
if Num[v]=0 then
Block(v,a)
num ← num+1
Num[v] ←num
L[v] ←num
for each w V, смежные c V do
if Num[w]=0 then
stack ←(v,w)
Block(w,v)
L[v] ←Min(L[v],L[w])
if L[w]≥Num[v] then
repeat
(v1, w1) ←stack
printf “(v1,w2)”
until(v1, w1) = (v,w)
else if(Num[w] ←Num[v]) and (w≠u) then
stack
L[v] ←Min(L[v], Num[v])
end if
end if
end if
end for
Метка вершины сочленения получает минимальный номер из всех вершин блока.
Вычислительная сложность: О(n+m)
Сильно связные компоненты. Алгоритм.
Слабо связные компоненты ориентированного графа легко получить игнорируя положения ребер и алгоритм нахождения связных компонент неориентированного графа.
Алгоритм:
Выполнить обход в глубину с сохранением номера окончания обработки узла.
Заменить все ребра ориентированного графа на противоположные.
Выполнить обход в глубину модиф. графа, при этом вершины рассматриваются в порядке убывания номера окончания обработки узла.
Деревья леса поиска в глубину получающиеся на предыдущем этапе представляют собой сильно связные компоненты графа.
Используется 2 раза обход в глубину.
Вычислительная сложность: О(n+m) – граф в виде списка смежности, О(n2) – граф в виде матрицы смежности.
Эйлеровы пути и циклы. Алгоритм нахождения эйлерова цикла.
Эйлеров путь в графе - произвольный путь, проходящий через каждое ребро графа ровно один раз, т.е. такой путь Vj,..., Vm+1, что каждое ребро Е появляется один раз как {Vj,V-+j} для некоторого i. Если Vj = Vm+1, то такой путь называется эйлеровым циклом.
Необходимое и достаточное условие существования эйлерова пути: эйлеров путь в графе существует тогда и только тогда, когда граф связан и содержит не более чем две вершины нечетной степени.
Если в графе нет вершин нечетной степени, то каждый эйлеров путь является эйлеровым циклом.
Пусть G = <V, Е> - связный граф, представленный списками СПИСОК[г], ve V. Алгоритм нахождения эйлерова цикла в графе построим следующим образом. Используем два стека: СТЕК1 и СТЕК2.
Выбираем произвольную вершину графа Vq и строим последовательно путь из этой вершины. Вершины этого пути помещаем в СТЕК1, а ребра удаляем из графа. Эти действия продолжаем до тех пор, пока оказывается, что путь удлинить, включив в него новую вершину, уже нельзя. Т.е. СПИСОК[у] = 0. Отметим, что тогда должно быть V = Vq , иначе это бы означало, что вершина v - нечетной степени. Таким образом из нашего графа был удален цикл, а вершины этого цикла находятся в стеке СТЕК1. При этом в графе, модифицированном таким образом, степень произвольной вершины остается четной. Вершина V = v0 переносится теперь из стека СТЕК1 в стек СТЕК2, а процесс повторяется, начиная с вершины, верхней в СТЕК1 (если ее список не пустой). Теперь снова в СТЕК1 помещается некоторый цикл, проходящий через эту вершину, и т.д. Процесс продолжается до тех пор, пока СТЕК1 не станет пустым.
Очевидно, что вершины, помещенные в СТЕК2, образуют некоторый путь, причем вершина v переносится в СТЕК2 только тогда, когда СПИСОК[у] = 0, т.е. когда все ребра, инцидентные этой вершине, представлены в СТЕКеl (парами соседних вершин). Отсюда следует, что по окончании алгоритма СТЕК2 содержит эйлеров цикл.
Алгоритм:
BEGIN
СТЕК1 := 0; СТЕК2 := 0;
v := произвольная вершина графа;
СТЕК1 <= v;
WHILE СТЕК1 /0DO BEGIN
v := top(СТЕКl); {v - верхний элемент СТЕК1}
IF СПИСОК[у] Ф 0
THEN BEGIN
u := первую вершину списка СПИСОК[у];
СТЕК1 <= u;
СПИСОК^] := СПИСОК^] \ { u }; {удалить ребро}
СПИСОКи] := СПИСОКи] \ { v }; {{ v, и } из графа}
v :=и;
END
ELSE { СПИСОК[у] = 0}
BEGIN
v <= СТЕКl;
СТЕК2 <= v;
END
END
END
Мы предполагаем здесь, что каждый из списков инцидентности СПИСОК[у], veV, реализован таким образом, что каждая вершина в этом списке содержит указатели на предыдущую и последующую вершины, а вершина и в списке СПИСОК[у] содержит указатель на вершину v в списке СПИСОК[и]. Это дает возможность удалить ребро {v, и} за число шагов, ограниченное константой. Тогда можно оценить вычислительную сложность алгоритма следующим образом.
Каждая итерация главного цикла (строка 5) либо помещает вершину в СТЕК1 и удаляет ребро из графа, либо переносит вершину из СТЕК1 в СТЕК2. Т.е. число итераций этого цикла О(т). Число же шагов в каждой итерации ограничено константой. Поэтому можно считать, что общая сложность алгоритма О(т). Алгоритм считается оптимальным.
Пример.
Эйлеров цикл, найденный с помощью нашего алгоритма: 1, 2, 3, 4, 5, 6, 7, 2, 8, 6, 9, 7, 8, 5,3, 1
Buler(G,stack2)
Stack1←0; Stack2←0;
Stack1←V0
While stack1≠0 do
V←Top(Stack1)
If Spisok[V]≠0 then
w←произв вер spisok[v]
Stack1←w
Spisok[v] ←Spisok[v]-w
Spisok[w] ←Spisok[w]-v
Else
v←Stack1
Stack0←V
End while
Return stack2
Множество фундаментальных циклов графа. Рекурсивный алгоритм нахождения множества фундаментальных циклов.
Если к стягивающему дереву <V, T> графа G = <V, E> мы добавим произвольную хорду e∈E\T, то возникший при этом подграф C = <V, T∪{e}> содержит в точности один цикл. Обозначим этот цикл через Ce. Множество C = {Ce : e∈E \ T} называют фундаментальным множеством циклов графа G (относительно стягивающего дерева <V, T>). Название "фундаментальное" связано с тем, что каждый цикл графа G можно достаточно просто получить из циклов множества G.
Нахождение фундаментального множества циклов имеет прикладное значение, например, при анализе электрических цепей. А именно, каждому фундаментальному циклу в графе, соответствующему данной электрической цепи, мы можем поставить в соответствие закон Кирхгофа для напряжений: сумма падения напряжений вдоль цикла равна 0. Нахождение фундаментального множества циклов позволяет выделить в математическом описании цепи независимые уравнения.
Алгоритм нахождения множества фундаментальных циклов основан на поиске в глубину и имеет структуру, аналогичную рекурсивному алгоритму нахождения стягивающего дерева.
Каждая новая вершина, встречающаяся в процессе поиска, помещается в стек, представленный таблицей СТЕК, и удаляется из стека после использования. Очевидно, что стек всегда содержит последовательность вершин от рассматриваемой в данный момент вершины v к корню.
Поэтому, если анализируемое нами ребро {v, и} замыкает цикл, то вершина и находится в стеке и цикл, замыкаемый ребром {v, и}, представлен группой элементов стека, начиная с v и кончая вершиной и.
1 PROCEDURE цикл(у);
{переменные d, пит, СТЕК, СПИСОК, WGN - глобальные}
2 BEGIN d := d+1; СТЕК[d] := v; пит := num+1; WGN[ ] := пит;
3 FOR uеСПИСОК[у] DO
IF WGN[u] = 0 THEN цикл(г)
ELSE IF (и Ф СТЕК[d-l]) and (WGN[v] > WGN[u])
THEN {ребро {v, и} замыкает новый цикл}
выписать цикл с вершинами
СТЕК[d], СТЕК[d-l], ..., СТЕК[с], где СТЕК[с] = и
8 d := d-1 {использованная вершина v удаляется из стека}
9 END (цикл}; Основная программа:
1 BEGIN
FOR veV DO WGN[r] := 0; num := 0; {инициализация}
d := 0; СТЕК[0] := 0; {d - число элементов в стеке}
FOR reV DO
5 IF WGN[r] = 0 THEN цикл(у)
6 END.
Оценим вычислительную сложность алгоритма. Отметим, что общее число шагов, не считая вычисления циклов, как и во всех алгоритмах, основанных на поиске в глубину, имеет порядок 0(n+m). К этому следует добавить суммарную длину всех циклов. Эта длина не превосходит (m-n+1), что дает общую сложность алгоритма O(nm), если отбросить вырожденный случай т=0.
Алгоритм Воршалла.
G=(V,E)Транзитивное замыкание ориентированного графа с n вершинами можно определить как булиеву матрицу Т размера n*n, в кот. Элемент на пересечении i-той строки и j-того столбца равен 1, если существует ориентированный путь положительной длины из вершины I в вершину j.В противном случае это значение равно 0. А-матрица смежности.
В.предложил строить транзит.замыкание как последовательность матриц размера n*n –элемент матрицы содержит 1, если есть путь из I в j, причем все промежут.верш.не превыш.номера k. Матрица содержит инф. о путях между вершинами гр., в кот. в кач.промежуточной верш.может использоваться только вершина 1. . Если существует путь от I до j и от k до j, то сущ-ет путь от k до i-появл.1.
Алгоритм Wavshell(A[1..n]*A[1..n])
1.R(0)A;
2.for k=1 to n do
3.for i=1 to n do
4.for j=1 to n do
5.R(k)[I,j]R(k-1)[I,j] or (R(k-1)[I,k] and R(k-1)[k,j]
6.end for
7.end for;
8.end for;
9.retirn R(n)
Вычислит.сложность=О(n3)