Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Тема_4_5_6.Деревья, графы.doc
Скачиваний:
14
Добавлен:
11.11.2019
Размер:
111.62 Кб
Скачать

Обходы графа в глубину и в ширину

Во многих задачах с использованием графов необходимо обходить все вершины и(или) ребра (дуги) графа. Обойти граф – это значит побывать во всех его вершинах по одному разу. Существует два классических алгоритма обхода графа – в глубину и в ширину.

Алгоритмы обхода дерева в глубину представляет обобщение алгоритма обхода дерева в прямом порядке.

Например, используя рекурсивную процедуру, алгоритм обхода графа G, заданного матрицей смежности, в глубину можно записать следующим образом:

procedure ОБХОД-В-ГЛУБИНУ(p:вершина);

begin

    Посетить вершину p;

    for all q from множества вершин, смежных с p do

        if q еще не посещалась then ОБХОД-В-ГЛУБИНУ(q) end

    end

end;

begin

    for all p from множества вершин G do

        if p еще не посещалась then ОБХОД-В-ГЛУБИНУ(p) end

    end

end.

Для того, чтобы отличать просмотренные вершины от непросмотренных можно ввести массив размерности n, чьи элементы будут принимать значения 1или 0 в зависимости от того просмотрена вершина или нет.

В результате работы алгоритма пройденные ребра графа образуют вместе с посещенными вершинами одно или несколько деревьев (по одному дереву для каждой компоненты связности графа). Если приписать пройденным ребрам ориентацию в соответствии с тем направлением, в каком они проходятся при выполнении алгоритма, то мы получим совокупность ордеревьев, причем их корнями будут служить все те вершины, которые в процессе работы алгоритма помещались в пустой стек. Например, для графа, изображенного на рис. а, описанным способом будут получены два ордерева, приведенных на рис. б. Порядок на всем множестве вершин графа, а также порядок вершин, смежных всякой его вершине, соответствует алфавитному порядку букв, помечающих вершины.

Нерекурсивный вариант алгоритма обхода графа G в глубину может иметь следующий вид:

procedure ОБХОД-В-ГЛУБИНУ-1(p: вершина);

begin

    Посетить вершину p и поместить ее в пустой стек S;

    while Стек S непуст do

            Пусть p -- вершина, находящаяся на верхушке стека S;

            if у p есть непосещенные смежные вершины then

                    Пусть q -- непосещенная вершина, смежная вершине p;

                    Пройти по ребру (p,q), посетить вершину q и поместить ее в стек S

            else Удалить вершину p из стека S

            end

    end

end;

Обход в ширину связного графа предполагает рассмотрение всех его вершин в порядке возрастания расстояния от некоторой вершины, с которой начался данный обход графа. То есть для вершины v сначала рассматриваются все вершины, смежные с ней и таким образом чем позже посмотрена вершина, тем позже она используются. Поэтому для хранения просмотренных вершин используется очередь. Например, в результате обхода графа G (рис. a) в ширину возможен следующий порядок посещения вершин: A, B, С, D, H, K, L, E, F, G  Следующий алгоритм позволяет осуществить обход в ширину любого связного графа G:

procedure ОБХОД-В-ШИРИНУ(p: вершина);

begin

    Поместить произвольную вершину p в пустую очередь O;

    while очередь O не пуста do

            Взять первую вершину p из очереди O;

            if p еще не посещалась then

                    Посетить вершину p и поместить в очередь O все непросмотренные вершины, смежные с p

            end

    end

end;