
25. Удаление элемента в двоичном дереве поиска.
Удаление узла Алгоритм:
Если дерево T пусто, остановиться
Иначе сравнить K с ключом X корневого узла n.
1.Если K>X, рекурсивно удалить K из правого поддерева Т.
2.Если K<X, рекурсивно удалить K из левого поддерева Т.
3.Если K=X, то необходимо рассмотреть два случая.
Если одного из детей нет, то значения полей второго ребёнка m ставим вместо соответствующих значений корневого узла, затирая его старые значения, и освобождаем память, занимаемую узлом m.
Если оба потомка присутствуют, то
найдём узел m, являющийся самым левым узлом правого поддерева;
скопируем значения полей (ключ, значение) узла m в соответствующие поля узла n.
у предка узла m заменим ссылку на узел m ссылкой на правого потомка узла m (который, в принципе, может быть равен ПУСТО).
освободим память, занимаемую узлом m (на него теперь никто не указывает, а его данные были перенесены в узел n).
Алгоритм Delete (T, k)
1.if T≠nil then
2.if k<T^.key then Delete (T^.left, k)
3.else if k>T^.key then Delete (T^.right, k)
4.else
5.if (T^.left=nil) and (T^.right=nil) then
6.p←T, T←nil, Dispose (p)
7.else if (T^.left=nil) then
8.p←T, T←T^.right, Dispose (p)
9.else if (T^.right=nil) then
10.p←T, T←T^.left, Dispose (p)
11.else Del (T^.right, p)
Del (T, p)
1.if T^.left=nil then
2.p^.key←T^.key
3.p1←T
4.T←T^.right
5.Dispose (p1)
6.return
7.else
8.Del (T^.left, p)
Вычислительная сложность.
Средний вариант – O(log n), худший случай – O(n).