Алгоритм построения Эйлерова цикла
Алгоритм
Описание алгоритма
Алгоритм находит Эйлеров цикл как в ориентированном, так и в неориентированном графе. Перед запуском алгоритма необходимо проверить граф на эйлеровость. Чтобы построить Эйлеров путь, нужно запустить алгоритм из вершины с нечетной степенью.
Алгоритм напоминает поиск в ширину. Главное отличие состоит в том, что пройденными помечаются не вершины, а ребра графа. Начиная со стартовой вершины строим путь, добавляя на каждом шаге не пройденное еще ребро, смежное с текущей вершиной. Вершины пути накапливаются в стеке . Когда наступает такой момент, что для текущей вершины все инцидентные ей ребра уже пройдены, записываем вершины из в ответ, пока не встретим вершину, которой инцидентны не пройденные еще ребра. Далее продолжаем обход по не посещенным ребрам.
Псевдокод
Код проверки графа на эйлеровость:
boolean checkForEulerPath(): int OddVertexfor if ( ) mod OddVertex++ if OddVertex // если количество вершин с нечетной степенью больше двух, то граф не является эйлеровым return false boolean visited( , false) // массив инициализируется значениями false for if ( ) dfs( , visited) break for if ( ) and not visited[ ] // если количество компонент связности, содержащие ребра, больше одной, return false // то граф не является эйлеровым return true // граф является эйлеровым
Код построения эйлерова пути:
function findEulerPath(): // если граф является полуэйлеровым, то алгоритм следует запускать из вершины нечетной степени for if ( ) mod break Stack .push( ) while not .empty() .top() for if ( ) // нашли ребро, по которому ещё не прошли .push( ) // добавили новую вершину в стек .remove( ) break if .top() .pop() // не нашлось инцидентных вершине рёбер, по которым ещё не прошли print( )
Доказательство корректности
Теорема: |
Данный алгоритм находит корректный эйлеров путь. |
Доказательство: |
TODO: Довести до ума
|
Рекурсивная реализация
function findEulerPath(: Vertex): for remove findEulerPath( ) print( )
Время работы
Если реализовать поиск ребер инцидентных вершине и удаление ребер за
Чтобы реализовать поиск за , для хранения графа следует использовать списки смежных вершин; для удаления достаточно добавить всем ребрам свойство бинарного типа.