Студопедия

Главная страница Случайная страница

КАТЕГОРИИ:

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Bool searchR (int v, int w)






{

if (v == w) return true; visited[v] = true;

typename Graph:: adjIterator A(G, v); for (int t = A.beg();! A.end(); t = A.nxt()) if (! visited[t])

if (searchR(t, w)) return true; return false; } public:

sPATH (const Graph & G, int v, int w): G(G), visited(G.V(), false) { found e searchR(v, w); } bool exists () const { return found; }

};

Программа 17.16 просто проверяет, существует тот или иной путь. Как следует рас­ширить ее с тем, чтобы она могла печатать ребра, составляющие путь? Рекурсивный под­ход предлагает простое решение:

■ Добавить оператор печати ребра v-t сразу же после того, как рекурсивный вызов
в функции searchR находит путь из t в w.

■ В вызове функции searchR из конструктора поменять местами v и w.

Первое изменение приводит к тому, что путь из v в w печатается в обратном порядке: если в результате вызов searchR(t, w) находит путь из t в w (и печатает ребра, составля­ющие этот путь, в обратном порядке), то печать пути t-v завершает решение задачи по­иска пути из v в w. Второе изменение меняет порядок: чтобы распечатать ребра, состав­ляющие путь из v в w, мы распечатываем путь из w в v в обратном порядке. (Этот прием работает только в случае неориентированных графов.) Мы могли бы применить эту стра­тегию для реализации функции АТД, которая вызывает функцию, переданную клиентом, для каждого ребра, составляющего путь (см. упражнение 17.88).

Рисунок 17.17 представляет собой пример динамики рекурсии. Как и в случае любой другой рекурсивной программы (в принципе, любой программы с вызовами функций), такую трассировку нетрудно вывести на печать: чтобы внести соответствующие измене­ния в программу 17.16, мы можем добавить переменную depth, значение которой увели­чивается на 1 при входе и уменьшается на 1 при выходе, чтобы отслеживать глубину ре-


Глава 1 7. Свойства и типы графов



 


курсии, затем поместить в начало рекурсивной фун­кции программный код, осуществляющий depth про­пусков при печати, за которыми следует соответствующая информация (см. упражнения 17.86 и 17.87).

Свойство 17.2. Мы можем найти путь, соединяю­щий две заданных вершины графа, за линейное время.

Рекурсивная функция поиска в глубину, реализо­ванная в программе 17.16, представляет собой до­казательство методом индукции того факта, что функция АТД определяет, существует искомый путь или нет. Такое доказательство легко можно расширить с целью установки, что в худшем слу­чае программа 17.16 проверяет все элементы мат­рицы смежности в точности один раз. Аналогично, мы можем показать, что подобного рода програм­мы, ориентированные на списки смежных вер­шин, проверяют в худшем случае все ребра графа в точности два раза (по разу в каждом направле­нии). ■

Мы используем термин линейный (linear) в контек­сте алгоритмов на графах, подразумевая под этим, что некоторое количественное значение не превосходит величины V+ Е (т.е. размеры графа), умноженной на соответствующий постоянный коэффициент. Как мы отметили в конце раздела 17.5, такое значение обыч­но не превосходит размера представления графа, ум­ноженного на соответствующий постоянный коэффи­циент. Свойство 17.2 сформулировано таким образом, что оно позволяет использовать представление разре­женных графов в виде списков смежных вершин и представление насыщенных графов в виде матрицы смежности, что, собственно говоря, и является нашей обычной практикой. Термин " линейный" не принято применять для описания алгоритма, который исполь­зует матрицу смежности и выполняется за время, про­порциональное V1 (даже если он линеен по отноше­нию к размерам представления графа), если рассматриваемый граф не принадлежит к числу насы­щенных. В самом деле, если мы используем пред­ставление графа в виде матрицы смежности, мы не можем подобрать алгоритм, линейный в смысле вре­мени исполнения, для любой задачи обработки графа, которая требует анализа каждого ребра.



Поделиться с друзьями:

mylektsii.su - Мои Лекции - 2015-2024 год. (0.006 сек.)Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав Пожаловаться на материал