- •Иркутский государственный технический университет
- •1. Определения графов
- •7.4.5. Массив дуг
- •8.4.2. Трансверсаль
- •8.5.4. Алгоритм нахождения максимального потока
- •8.6.3. Выделение компонент сильной связности
- •8.7.1. Длина дуг
- •8.7.2. Алгоритм Флойда
- •8.7.3. Алгоритм Дейкстры
- •Глава 9 Деревья
- •9.1. Свободные деревья
- •9.1.1. Определения
- •9.1 .2. Основные свойства деревьев
- •9.2. Ориентированные, упорядоченные и бинарные деревья
- •9.2.1. Ориентированные деревья
- •9.2.2. Эквивалентное определение ордерева
- •9.2.3. Упорядоченные деревья
- •9.2.4. Бинарные деревья
- •9.3. Представление деревьев в эвм
- •9.3.1. Представление свободных, ориентированных и упорядоченных деревьев
- •9.3.2. Представление бинарных деревьев
- •9.3.3. Обходы бинарных деревьев
- •9.3.4. Алгоритм симметричного обхода бинарного дерева
- •9.4. Деревья сортировки
- •9.4.1. Ассоциативная память
- •9.4.2. Способы реализации ассоциативной памяти
- •9.4.3. Алгоритм бинарного (двоичного) поиска
- •9.4.4. Алгоритм поиска в дереве сортировки
- •9.4.5. Алгоритм вставки в дерево сортировки
- •9.4.6. Алгоритм удаления из дерева сортировки
- •9.4.7. Вспомогательные алгоритмы для дерева сортировки
- •9.4.8. Сравнение представлений ассоциативной памяти
- •9.4.9. Выровненные деревья
- •9.4.10. Сбалансированные деревья
- •9.5. Кратчайший остов
- •9.5.1. Определения
- •9.5.2. Схема алгоритма построения кратчайшего остова
- •9.5.3. Алгоритм Краскала
- •Глава 10 Циклы
- •10.1. Фундаментальные циклы и разрезы
- •10.1.1. Циклы и коциклы
- •10.1.2. Независимые множества циклов и коциклов
- •10.1.3. Циклический и коциклический ранг
- •10.2. Эйлеровы циклы
- •10.2.1. Эйлеровы графы
- •10.2.2. Алгоритм построения эйлерова цикла в эйлеровом графе
- •10.2.3. Оценка числа эйлеровых графов
- •10.3. Гамильтоновы циклы
- •10.3.1. Гамильтоновы графы
- •10.3.2. Задача коммивояжера
- •Глава 11 Независимость и покрытия
- •11.1. Независимые и покрывающие множества
- •11.1.1. Покрывающие множества вершин и ребер
- •11.1.2. Независимые множества вершин и ребер
- •11.1.3. Связь чисел независимости и покрытий
- •11.2. Построение независимых множеств вершин
- •11.2.1. Постановка задачи отыскания наибольшего независимого множества вершин
- •11.2.2. Поиск с возвратами
- •11.2.3. Улучшенный перебор
- •11.2.4. Алгоритм построения максимальных независимых множеств вершин
- •11.3. Доминирующие множества
- •11.3.1. Определения
- •11.3.2. Доминирование и независимость
- •11.3.3. Задача о наименьшем покрытии
- •11.3.4. Эквивалентные формулировки знп
- •11.3.5. Связь знп с другими задачами
- •Глава 12 Раскраска графов
- •12.1. Хроматическое число
- •Ух, . . . ,Vn одноцветные классы,доказательство
- •12.2. Планарность
- •12.2.2. Эйлерова характеристика
- •12.2.3. Теорема о пяти красках
- •12.3. Алгоритмы раскрашивания
- •12.3.1. Точный алгоритм раскрашивания
- •12.3.2. Приближенный алгоритм последовательного раскрашивания
- •12.3.3. Улучшенный алгоритм последовательного раскрашивания
9.4.6. Алгоритм удаления из дерева сортировки
Следующий алгоритм удаляет из дерева сортировки узел с указанным ключом. Если узла с указанным ключом нет в дереве, то ничего не делается. Вспомогательные процедуры Find и Delete описаны в следующем подразделе.
Алгоритм 9.5. Удаление узла из дерева сортировки
Вход: дерево сортировки Т, заданное указателем на корень; ключ а.
Выход: модифицированное дерево сортировки Т.
Find(T, a,p, q, s) { поиск удаляемого узла }
if p = nil then
return Т { нет такого узла — ничего делать не нужно }
end if
if p.r = nil then
Delete(p, q,p.l,s) { случай 1, см. рис. 9.11 слева } else
u:=p.r
if u.l = nil then
u.l: =p.l
Delete(p,q,u,s) { случай 2, см. рис. 9.11 в центре }
else
w : = u;v : = u.l
while v.l nil do
w : = v; v : =v.l
end while
p.i: = v.i
Delete(v, w, v.r,-1) { случай 3, см. рис. 9.11 справа }
end if
end if
return Т
обоснование
Удаление узла производится перестройкой дерева сортировки. При этом возможны три случая (не считая тривиального случая, когда удаляемого узла нет в дереве и ничего делать не нужно).
1. Правая связь удаляемого узла р пуста (см. рис. 9.11 слева). В этом случае левое поддерево 1 узла р подцепляется к родительскому узлу q с той же стороны, с которой был подцеплен узел р. Условие дерева сортировки, очевидно, выполняется.
2. Правая связь удаляемого узла р не пуста и ведет в узел и, левая связь кото рого пуста (см. рис. 9.11 в центре). В этом случае левое поддерево 1 узла в подцепляется к узлу и слева, а сам узел и подцепляется к родительскому узлу q с той же стороны, с которой был подцеплен узел р. Нетрудно проверить что условие дерева сортировки выполняется и в этом случае.
Рис. 9.11. Иллюстрация к алгоритму удаления узла из дерева сортировки
3. Правая связь удаляемого узла р не пуста и ведет в узел и, левая связь которого не пуста. Поскольку дерево сортировки конечно, можно спуститься от узла и до узла v, левая связь которого пуста (см. рис. 9.11 справа). В этом случае выполняются два преобразования дерева. Сначала информация в узле р заменяется на информацию узла v. Поскольку узел v находится в правом поддереве узла р к в левом поддереве узла и, имеем p.i < v.i < u.i. Таким образом, после этого преобразования условие дерева сортировки выполняется. Далее правое поддерево 4 узла v подцепляется слева к узлу w, а сам узел v удаляется. Поскольку поддерево 4 входило в левое поддерево узла w, условие дерева сортировки также сохраняется.
ЗАМЕЧАНИЕ
В книге [11], из которой заимствован данный алгоритм, показано, что хотя алгоритм «выглядит несимметричным» (правые и левые связи обрабатываются по-разному), на самом деле в среднем характеристики дерева сортировки не искажаются.
9.4.7. Вспомогательные алгоритмы для дерева сортировки
Алгоритмы трех предыдущих разделов используют вспомогательные функции, описанные здесь.
1. Поиск узла — функция Find.
Вход: дерево сортировки Т, заданное указателем на корень; ключ а.
Выход: р — указатель на найденный узел или nil, если в дереве нет такого ключа; q — указатель на отца узла р; s — способ подцепления узла q к узлу р (s = -1, если р слева от q; s = +1, если р справа от q; s = 0, если р — корень).
p: = T;q: = nil; s: = 0 { инициализация }
while p nil do
if p.i = a then
return p, q, s
end if
q: = p { сохранение значения р }
if a < p.i then
p: = p.l; s : = - 1 { поиск слева }
else
p: =p.r; s : = +1 { поиск справа }
end if
end while
ОТСТУПЛЕНИЕ
В этой простой функции стоит обратить внимание на использование указателя q, который отслеживает значение указателя р «с запаздыванием», то есть указатель q «помнит» предыдущее значение указателя р. Такой прием полезен при обходе однонаправленных структур данных, в которых невозможно вернуться назад.
2. Удаление узла - процедура Delete.
Вход: р1 — указатель на удаляемый узел; р2 — указатель на подцепляющий узел; рЗ —
указатель на подцепляемый узел; s — способ подцепления.
Выход: преобразованное дерево.
if s = -1 then
p2.l : =рЗ { подцепляем слева }
end if
if s = +1 then
p2.r : = рЗ { подцепляем справа }
end if
dispose(p1) { удаляем узел }
3. Создание нового узла — конструктор NewNode.
Вход: ключ а.
Выход: указатель р на созданный узел.
new(p);p.i: = a;p.l:=nil; p.r : = nil
return p