- •Структуры и алгоритмы обработки данных
- •Часть 1
- •Последовательное представление линейных списков
- •Связанное представление линейных списков
- •Очередь
- •Связанное представление матриц
- •Бинарное дерево поиска. Построение и поиск элемента
- •Бинарное дерево поиска. Удаление элемента
- •Линейные списки с индексами. Построение и поиск элемента. Способы коррекции
- •Инвертированные списки
- •Построение словаря с использованием деревьев
- •Построение словаря с использованием матриц
Бинарное дерево поиска. Удаление элемента
На рис.1 приведена структура БДП, а на рис.2 – структура отдельного узла дерева. На рис.2 поле Inf – информационное поле, поле Left – указатель на «потомка» слева, Right – указатель на «потомка» справа. Стоит отметить, что в БДП не может быть одинаковых ключей.
Рис.1 Рис.2
left
inf
right
Структура БДП:
type
point = ^element; {указатель в списке }
element = record {элемент списка }
inf: integer; {информационная часть }
left, right: point {указатели на «потомков»}
end;
Удаление элемента:
При удалении сначала осуществляется поиск удаляемой вершины. При этом возможны три случая:
Удаляемый элемент лист. В этом случае узел просто удаляется.
Узел имеет одного сына. Тогда родительскому указателю присваивается значение сына, а сам элемент удаляется из памяти.
Узел имеет двух сыновей. В этом случае в левом поддереве ищем самый правый узел (узел r), его ключ присваиваем полю inf удаляемого узла. Правой ссылке родительского узла элемента R присваиваем значение левой ссылки элемента r и удаляем из памяти узел R. Или в правом поддереве ищем самый левый узел (узел L), его ключ присваиваем полю inf удаляемого узла. Левой ссылке родительского узла элемента L присваиваем значение правой ссылки элемента L и удаляем из памяти узел L.
На PASCAL это выглядит следующим образом:
procedure DeleteNode (x:integer; var p:point);
var
q:point;
procedure Del (var r:point);
begin
if r^.right=nil then
begin
q^.inf:=r^.inf;
q:=r;
r:=r^.left;
end
else Del(r^.right);
end;
begin
if p=nil then
begin
writeln('Удаление. Элемент',x,'не найден');
readkey;
end
else
if x<p^.inf then DeleteNode(x, p^.left)
else
if x>p^.inf then DeleteNode(x, p^.right)
else
begin
q:=p;
if q^.right=nil then p:=q^.left
else
if q^.left=nil then p:=q^.right
else Del(q^.left);
dispose(q);
writeln('Удаление. Элемент ',x,' успешно удалён');
readkey;
end;
end;
АВЛ – дерево. Построение и поиск элемента
АВЛ – бинарное дерево, для любой вершины которого разность высот левого и правого поддеревьев не превышает единицы (Сбалансированные по высоте деревья).
Построение:
Пусть даны ключи в последовательности 4, 5, 7, 2, 1, 3, 6 тогда построение такое:
Построение выполняется путём балансировки дерева.
Поиск:
Нужная вершина в дереве ищется по ключу.
Пусть построено некоторое дерево и требуется найти звено с ключом X. Сначала сравниваем с X ключ, находящийся в корне дерева. В случае равенства поиск закончен и нужно возвратить указатель на корень в качестве результата поиска. В противном случае переходим к рассмотрению вершины, которая находится слева внизу, если ключ X меньше только что рассмотренного, или справа внизу, если ключ X больше только что рассмотренного. Сравниваем ключ X с ключом, содержащимся в этой вершине, и т.д. Процесс завершается в одном из двух случаев:
1. Найдена вершина, содержащая ключ, равный ключу X;
2. В дереве отсутствует вершина, к которой нужно перейти для выполнения очередного шага поиска.
В первом случае возвращается указатель на найденную вершину.
АВЛ – дерево. Удаление элемента
АВЛ – бинарное дерево, для любой вершины которого разность высот левого и правого поддеревьев не превышает единицы (Сбалансированные по высоте деревья).
Удаление:
При удалении сначала осуществляется поиск удаляемой вершины. Возможны следующие случаи:
1. Удаляемый элемент лист. В этом случае узел просто удаляется, производим балансировку дерева.
2. Узел имеет двух сыновей. В этом случае в левом поддереве ищем самый правый узел (узел r), его ключ присваиваем полю inf удаляемого узла. Правой ссылке родительского узла элемента r присваиваем значение левой ссылки элемента r и удаляем из памяти узел r., балансируем дерево.
В – дерево. Построение и поиск элемента
Механизм классических B-деревьев был предложен в 1970 г. Бэйером и МакКрейтом. B-дерево порядка n представляет собой совокупность иерархически связанных страниц внешней памяти (каждая вершина дерева – страница), обладающая следующими свойствами:
1. Каждая страница содержит не более 2*n элементов (записей с ключом).
2. Каждая страница, кроме корневой, содержит не менее n элементов.
3. Если внутренняя (не листовая) вершина B-дерева содержит m ключей, то у нее имеется m+1 страниц-потомков.
4. Все листовые страницы находятся на одном уровне.
Пример B-дерева степени 2 глубины 3 приведен на рисунке:
Классическое B-дерево порядка 2
Поиск:
Предположим, что происходит поиск ключа K. В основную память считывается корневая страница B-дерева. Предположим, что она содержит ключи k1, k2, ..., km и ссылки на страницы p0, p1, ..., pm. В ней последовательно (или с помощью какого-либо другого метода поиска в основной памяти) ищется ключ K. Если он обнаруживается, поиск завершен. Возможны три ситуации:
1. Если в считанной странице обнаруживается пара ключей ki и k(i+1) такая, что ki < K < k(i+1), то поиск продолжается на странице pi.
2. Если обнаруживается, что K > km, то поиск продолжается на странице pm.
3. Если обнаруживается, что K < k1, то поиск продолжается на странице p0.
Для внутренних страниц поиск продолжается аналогичным образом, пока либо не будет найден ключ K, либо мы не дойдем до листовой страницы. Если ключ не находится и в листовой странице, значит ключ K в B-дереве отсутствует.
В – дерево. Удаление элемента
B-дерево порядка n представляет собой совокупность иерархически связанных страниц внешней памяти (каждая вершина дерева - страница), обладающая следующими свойствами:
Каждая страница содержит не более 2*n элементов (записей с ключом).
Каждая страница, кроме корневой, содержит не менее n элементов.
Если внутренняя (не листовая) вершина B-дерева содержит m ключей, то у нее имеется m+1 страниц-потомков.
Все листовые страницы находятся на одном уровне.
Пример B-дерева степени 2 глубины 3 приведен на рисунке:
Классическое B-дерево порядка 2
Удаление элемента:
Различают два случая - удаление ключа из листовой страницы и удаления ключа из внутренней страницы B-дерева. В первом случае удаление производится просто: ключ просто исключается из списка ключей. При удалении ключа во втором случае для сохранения корректной структуры B-дерева его необходимо заменить на минимальный ключ листовой страницы, к которой ведет последовательность ссылок, начиная от правой ссылки от ключа K (это минимальный содержащийся в дереве ключ, значение которого больше значения K). Тем самым, этот ключ будет изъят из листовой страницы
Начальный вид B-дерева
B-дерево после удаления ключа 25
Поскольку в любом случае в одной из листовых страниц число ключей уменьшается на единицу, может нарушиться требование, что любая, кроме корневой, страница B-дерева должна содержать не меньше n ключей. Если это случается, начинает работать процедура переливания ключей. Берется одна из соседних листовых страниц (с общей страницей-предком); ключи, содержащиеся в этих страницах, а также средний ключ страницы-предка поровну распределяются между листовыми страницами, и новый средний ключ заменяет тот, который был заимствован у страницы-предка.
Результат удаления ключа 38 из B-дерева
Может оказаться, что ни одна из соседних страниц непригодна для переливания, поскольку содержат по n ключей. Тогда выполняется процедура слияния соседних листовых страниц. К 2*n-1 ключам соседних листовых страниц добавляется средний ключ из страницы-предка (из страницы-предка он изымается), и все эти ключи формируют новое содержимое исходной листовой страницы. Поскольку в странице-предке число ключей уменьшилось на единицу, может оказаться, что число элементов в ней стало меньше n, и тогда на этом уровне выполняется процедура переливания, а возможно, и слияния. Так может продолжаться до внутренних страниц, находящихся непосредственно под корнем B-дерева. Если таких страниц всего две, и они сливаются, то единственная общая страница образует новый корень. Высота дерева уменьшается на единицу, но по-прежнему длина пути до любого листа одна и та же. Начальный вид B-дерева
B-дерево после удаления ключа 29