Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

11.4. Наборы и Структуры Союза/Находить 535

Мы осуществляем каждую из трех фундаментальных операций по набору, используя универсальный ver-

Сьон алгоритма слияния, который берет, как введено, две сортированных последовательности, представляющие входные наборы, и строит последовательность, представляющую набор продукции, быть им союз, пересечение или вычитание входных наборов. Случайно, мы определили эти op-erations так, чтобы они изменили содержание набора включенный. Альтернативно, мы, возможно, определили эти функции так, чтобы они не изменили A, но возвратили новый набор вместо этого.

Универсальный алгоритм слияния многократно исследует и сравнивает текущий el - ements a и b входной последовательности A и B, соответственно, и узнает ли <b, = b или a> b. Затем основанный на результате этого сравнения, это удерживает - шахты, должно ли это скопировать один из элементов a и b до конца последовательности продукции C. Это определение сделано основанным на особой операции, которую мы выполняем, быть им союз, пересечение или вычитание. Например, в операции союза, мы продолжаем двигаться следующим образом:

• Если <b, мы копируем до конца C и продвижения к следующему элементу A

• Если = b, мы копируем до конца C и продвижения к следующим элементам A

и B

• Если a> b, мы копируем b до конца C и продвижения к следующему элементу B

Выполнение универсального слияния

Давайте проанализируем продолжительность универсального слияния. При каждом повторении мы выдерживаем сравнение

два элемента входных последовательностей A и B, возможно скопируйте один элемент к последовательности продукции и прогресс текущий элемент A, B, или обоих. Предполагая, что сравнение и копирование элементов берут O (1) время, полная продолжительность - O (nA + nB), где nA - размер A, и nB - размер B; то есть, универсальное слияние занимает время пропорциональное ряду элементов. Таким образом у нас есть следующее: Суждение 11.8: набор ADT может быть осуществлен с заказанной последовательностью и универсальной схемой слияния, которая поддерживает операционный союз, пересекитесь и вычтите в O (n) время, где n обозначает сумму размеров включенных наборов.

Универсальное слияние как образец метода шаблона

Универсальный алгоритм слияния основан на образце метода шаблона (см. Секунду -

tion 7.3.7). Образец метода шаблона - шаблон программирования, описывающий универсальный механизм вычисления, который может быть специализирован, пересмотрев определенные шаги. В этом случае мы описываем метод, который сливает две последовательности в одну и может быть специализирован поведением трех абстрактных методов.

Кодовые Фрагменты 11.9 и 11.10 показывают Слияние класса, обеспечивающее C ++ im-plementation универсального алгоритма слияния. У этого класса нет участников данных. Это определяет слияние государственной функции, которое сливает эти два списка A и B, и хранит

536

Глава 11. Сортировка, Наборы и Выбор приводят к C. Это обеспечивает три виртуальных функции, fromA, fromB, и fromBoth. Это чистые виртуальные функции (то есть, они не определены здесь), но отвергнуты в подклассах Слияния, чтобы достигнуть желаемого эффекта. Функция fromA определяет действие, которое будет взято, когда следующий элемент, который будет отобран в слиянии, от A. Точно так же fromB определяет действие, когда следующий элемент, который будет отобран, от B. Наконец, fromBoth - действие, которое будет взято, когда два элемента A и B равны, и следовательно оба должны быть отобраны.

шаблон <typename E>

Слияние класса

общественность:

станд. typedef:: список <E> Список; недействительное слияние (List& A, List& B, List& C);

защищенный:

typedef typename Список:: iterator Itor;

виртуальная пустота fromA (константа E& a, List& C) = 0;

// // // // // // //

универсальное Слияние глобальный список типов печатает универсальную функцию слияния местные типы iterator, печатает отвергнутые функции

виртуальная пустота fromBoth (константа E& a, константа E& b, List& C) = 0; виртуальная пустота fromB (константа E& b, List& C) = 0;

;

Кодовый Фрагмент 11.9: Определение Слияния класса для универсального слияния.

Слияние функции, которое представлено в Кодовом Фрагменте 11.10, выступает

фактическое слияние. Это структурно подобно основанной на списке процедуре слияния, данной в Кодовом Фрагменте 11.3. Вместо того, чтобы просто брать элемент из списка A или списка B, это призывает одну из виртуальных функций, чтобы выполнить соответствующую специализированную задачу. Конечный результат сохранен в списке C.

шаблон <typename E> //универсальное слияние

недействительное Слияние <E>:: слияние (List& A, List& B, List& C)

Itor pa = A.begin (); //элементы А

Свинец Itor = B.begin (); //элементы Б

в то время как (pa! = A.end () && свинец! = B.end ())

если (*pa <*свинец)

fromA (*pa ++, C);

еще, если (*pa == *свинец)

fromBoth (*pa ++, *свинец ++, C);

еще

fromB (*pb ++, C);

в то время как (pa! = A.end ())fromA (*pa ++, C);, в то время как (свинец! = B.end ())fromB (*pb ++, C);

//главная петля слияния

//возьмите от A

//возьмите от обоих

//возьмите от B

//возьмите отдых от//, берут отдых от B

Кодовый Фрагмент 11.10: членское слияние функции, которое осуществляет универсальное слияние

для Слияния класса.