Опубликован: 26.09.2006 | Доступ: свободный | Студентов: 1811 / 503 | Оценка: 4.25 / 4.12 | Длительность: 17:09:00
ISBN: 978-5-9556-0066-6
Специальности: Программист, Математик
Лекция 3:

Разделенные множества

< Лекция 2 || Лекция 3: 123456 || Лекция 4 >

Представление разделенных множеств древовидной структурой

Пусть, по-прежнему, U = \{1, 2\dts n\} — множество, из элементов которого будет строиться коллекция. Каждое подмножество коллекции представляется корневым деревом, узлы которого являются элементами этого подмножества, то есть отождествляются с номерами из множества \{1, 2\dts n\}. Корень дерева используется в качестве имени соответствующего подмножества (канонический элемент). Для каждого узла дерева определяется узел p(x), являющийся его родителем в дереве; если x — корень, то полагаем p(x) =
x.

Фактически в памяти компьютера это дерево будем представлять массивом p[1\ldots n] так, что p(x) будет предком узла x, если x не является корнем, и p(x) = x, если x — корень. Если же x не входит ни в одно из подмножеств коллекции, то p(x) = 0.

Рассмотрим пример. Пусть U = \{1, 2\dts 7\} и коллекция состоит из двух подмножеств \{1, 2, 3, 7\} и \{4, 6\}. Деревья, представляющие эти подмножества, могут быть такими, как на рис.3.1. Кружочки обозначают узлы дерева; указатели на родителей представлены при помощи стрелок. Именем одного из этих подмножеств является 3, другого — 6:


Рис. 3.1.

Реализация операций с помощью древовидной структуры

Операция СОЗДАТЬ ( x ) назначает в качестве родителя узла x сам узел x с помощью присваивания p[x]
:= x. Таким образом, время выполнения операции есть O(1). В результате выполнения операции СОЗДАТЬ( x ) образуется новое одновершинное дерево с петлей в корне, изображенное на рис. 3.2.


Рис. 3.2.

Если к коллекции подмножеств, изображенных на рис. 3.1, применить операцию СОЗДАТЬ (5), то получим коллекцию, изображенную на рис. 3.3.


Рис. 3.3.

Операция ОБЪЕДИНИТЬ ( x, y ) назначает узел y родителем узла x с помощью присваивания p[x]:= y. Заметим, что x и y должны быть до выполнения рассматриваемой операции корнями соответствующих деревьев. Именем вновь образованного подмножества будет y, а x перестанет быть именем какого-либо множества. Время выполнения этой операции есть O(1).


Рис. 3.4.

Если применить операцию ОБЪЕДИНИТЬ (3, 6) к коллекции, представленной на рис. 3.3, то получим коллекцию, состоящую из двух подмножеств \{1, 2, 3, 4, 6, 7\} и \{5\}, — изображенную на рис. 3.4. Именем первого из этих подмножеств будет 6, второго — 5.

Операция НАЙТИ ( x,y ) осуществляется продвижением по указателям на родителей от узла x до корня дерева. В качестве y берется этот корень. Описанные действия можно реализовать с помощью операторов

\formula{
\t \while\ p[x] \ne x\ \t \do\ x := p[x];\ y := x;
}

Очевидно, что время выполнения данной операции есть O(h), где h — длина пути из узла x в корень соответствующего дерева. Но заметим, что при выполнении операций СОЗДАТЬ и ОБЪЕДИНИТЬ возможно образование дерева в виде линейной цепочки из n узлов, изображенной на рис. 3.5.


Рис. 3.5.

К такой цепочке может привести, например, следующая последовательность операций

СОЗДАТЬ ( \bs 1 );

СОЗДАТЬ ( \bs 2 );

\dots \dots \dots

СОЗДАТЬ ( \bs n );

ОБЪЕДИНИТЬ ( \bs 1, \bs 2 );

ОБЪЕДИНИТЬ ( \bs 2, \bs 3 );

\dots \dots \dots

ОБЪЕДИНИТЬ ( \bs n-{\bs 1},{\bs n} );

Как видим, h может достигать величины n, поэтому трудоемкость операции НАЙТИ является величиной O(n).

Худший случай применения операции НАЙТИ в данной ситуации — это НАЙТИ ( 1,y ). В этом случае необходимо сделать n -
1 переход по ссылкам на родителей, чтобы дойти от узла 1 к корню дерева n, и один переход, чтобы узнать, что родитель узла n есть сам узел n.

Если операция СОЗДАТЬ выполняется n раз, то время выполнения последовательности, составленной из m операций ОБЪЕДИНИТЬ и/или НАЙТИ, при рассматриваемой реализации разделенных множеств есть величина O(m\cdot n). Действительно, время выполнения m операций ОБЪЕДИНИТЬ, очевидно, есть O(m), так как время выполнения одной такой операции есть константа. Время выполнения m операций НАЙТИ есть O(m\cdot n), так как время выполнения одной такой операции есть O(n). Итак, время выполнения m произвольных операций есть O(m\cdot
n).

< Лекция 2 || Лекция 3: 123456 || Лекция 4 >
Антон Сиротинкин
Антон Сиротинкин

на стр 6, лекции 3, Очевидно "Ck <= модуль(Gk(е))*b(k+1)" (1) - , подскажите что значит "модуль" и почему это очевидно...