- •Предназначено студентам очной формы обучения.
- •Введение
- •1. Оценки сложности алгоритмов
- •1.1. Определение понятия алгоритм
- •1.2. Оценка сложности алгоритмов
- •2. Линейные структуры данных
- •2.1. Методы организации и хранения линейных списков
- •2.2. Операции со списками при последовательном хранении
- •2.3. Операции со списками при связном хранении
- •2.4. Организация двусвязных списков
- •Задания для самоконтроля
- •2.5. Стеки и очереди
- •2.6. Сжатое и индексное хранение линейных списков
- •3. Сортировка и слияние
- •3.1. Пузырьковая сортировка
- •3.2. Сортировка вставкой
- •3.3. Сортировка посредством выбора
- •3.4. Сортировка квадратичной выборкой
- •3.5. Слияние списков
- •3.6. Сортировка списков путем слияния
- •3.7. Быстрая и распределяющая сортировки
- •4. Поиск
- •4.1. Последовательный поиск
- •4.2. Бинарный поиск
- •4.4. Методы вычисления адреса
- •4.5. Выбор в линейных списках
- •5. Рекурсия
- •6. Алгоритмы на графах и сетях
- •6.1. Исходные понятия
- •6.2. Матричные представления графов
- •6.3. Другие представления графов
- •6.4. Поиск в глубину как система исследования графа
- •6.5. Перебор цепей поиском в глубину
- •6.6. Взвешенные графы. Ориентированные графы
- •6.7. Нахождение фундаментального множества циклов
- •6.8. Выявление мостов и точек сочленений
- •6.9. Поиск в ширину как система исследования графа
- •6.10. Кратчайшие пути, ведущие от заданного узла X ко всем прочим
- •6.11. Алгоритм Дейкстры нахождения кратчайших путей во взвешенном графе
- •6.12. Улучшения алгоритма Дейкстры
- •6.13. Построение кратчайшего каркаса
- •6.14. Нахождение всевозможных кратчайших путей в графе
- •6.15. Потоковые задачи
- •6.16. Пример практической задачи на графах
- •7. Генераторы случайных и псевдослучайных последовательностей
- •7.1. Общая постановка задачи
- •7.3. Генератор случайных чисел, поставляемый с системой
- •7.4. Генератор с малым кодом
- •7.5. Генератор Парка-Миллера
- •7.6. Улучшенная версия генератора Парка-Миллера
- •7.7. Быстрый генератор для 32-битового представления целых и действительных чисел
- •7.8. Алгоритм л'Экюера, комбинирующий две последовательности
- •Оглавление
- •7. Генераторы случайных и псевдослучайных последовательностей 144
- •394026 Воронеж, Московский просп., 14
6.9. Поиск в ширину как система исследования графа
Поиск в ширину имеет отправной узел X, а процесс его представляет как бы волну, распространяющуюся в графе от "точки возмущения" X и захватывающую все новые узлы. После узла X обрабатываются все узлы, смежные с X - "дети" X, затем "дети детей" - "внуки" X и т.д. В конце концов, в связном графе все узлы, "поколение за поколением" будут обработаны. Дисциплина обслуживания - FIFO (см. п.1.5), поэтому узлы заносятся в очередь О. Признаком завершения поиска в ширину является исчерпание очереди О.
Повторное рассмотрение узла исказило бы систему; чтобы этого избежать, посещенные узлы j снабжаются признаком Rj 0. Изначально вектор R содержит нули. Таковы две используемые структуры. В качестве Rj можно записывать "отца" узла j: вектор признаков R заодно будет представлять широтный каркас. В нем узлы одного поколения занимают ярус. Хорда либо связывает узлы одного яруса, либо узлы 2 соседних ярусов.
Если применить поиск в ширину к графу G1 (п.5.4), будет построена очередь
5 3 8 9 2 4 7 1 6
узел X дети внуки правнуки сформирован широтный каркас:
В несвязном графе процесс заканчивается после посещения всех узлов одной компоненты связности. Поэтому поиск в ширину можно использовать для проверки связности графа и выделения компонент связности.
Пример 6.9.
Применим поиск в ширину к графу G1, начиная с узла 1.
Constn=9; {Значение п не должно превышать 254}
Type matr=Array [1..n,1..n] of byte; vek=Array[1..n] of byte;
Const A: matr = ( (0,1,0,1,0,0,0,1,0),
(1,0,1,0,0,1,0,0,0),
(0,1,0,1,1,0,1,0,0),
(1,0,1,0,0,0,1,0.0),
(0,0,1,0,0,0,0,1,1),
(0,1,0,0,0,0,0,0,0),
(0,0,1,1,0,0,0,0,0),
(1,0,0,0,1,0,0,0,0),
(0,0,0,0,1,0,0,0,0) );
Var O:vek;j,k:byte;
Procedure Svjaz (Var A:matr; Var O:vek; Var k:byte);
Var R:vek; i,j,L:byte;
Begin For j:=1 to n do R[j]:=0;
i:=1; k:=1; {/ - указатель головы, k - конца очереди}
O[k]:= 1; {Заносим в очередь отправной узел}
R[1 ]:= n+1; (Отмечаем посещение узла 1}
RepeatL:= O[i]; {Номер L текущего узла берем из очереди}
Forj:=1 tondoIf (A[L,j] <>0) And (R[j] = 0) Then BeginR[j]:=L; k:=k+1; O[k]:=jEnd; {Ставим "сына" jузла L в очередь} i:=i+1 {Переходим к следующему "отцу", пока не опустеет очередь}
Until i > k
End;
BEGIN Svjaz (A, O, k);
If k=n Then Writeln ('Граф G1 - связный')
Else Begin Write ('Узлы 1-йкомпоненты: ', O[1]);
For j:=2 to k do Write (', ', 0[j]); Writeln End; Readln;
END.
Сложность поиска в ширину при нематричном представлении графа равна O(n+m), ибо рассматриваются все n узлов и m ребер. Использование матрицы смежности приводит к оценке О(n2 ).
В широтном каркасе любой узел связан с потомками кратчайшими цепями, что и обусловливает область применений поиска в ширину.
Рассмотрим ряд понятий. Расстояние rij между vi , vj - это длина кратчайшей цепи, ведущей от vi к vj , а диаметр графа - наибольшее из значений rij . Эксцентриситет еj узла j - расстояние от узла до наиболее удаленного от него узла. Диаметр графа является наибольшим из эксцентриситетов, а радиус графа - наименьшим. Если узел jнедостижим от узла i, считают, что rij = .
В связном графе медиана - это узел, сумма расстояний от которого до прочих узлов минимальна. У периферийного узла эксцентриситет равен диаметру, а у центрального - радиусу. Множество центральных узлов называют центром графа. Назовем S-периферией (S-окружением) узла j множество узлов, расстояние до которых больше S (не больше S). Нахождение всех указанных характеристик выполняют с помощью поиска в ширину. Еще одно весьма важное применение рассмотрим в п.5.15.
Задание 6.9.
1. Испытайте программу примера 5.9 на несвязном графе.
2. Реализуйте пример 5.9, используя для описания графа G1 структуру с оглавлением. Обдумайте изменения, необходимые для отражения в массиве О
всех компонент связности графа.