摘要:欧拉回路的基本定义是从一个起点出发,遍历所有的边最后回到起点.欧拉通路则不要求回到初始点.
基本思路:
[1]首先给出两个定理,如果一个无向图存在欧拉回路,那么它一定每一个节点的度数都是偶数.这很容易理解,假如某个节点的出度与入度不等,那么终究有某次访问该点导致不能出去.
[2]如果一个无向图存在欧拉通路,要么它每个节点的度数都是偶数,要么存在两个节点的度数是奇数.而且如果有两个节点是奇数,那么该回路只能从一个奇数节点出发,到另一个节点结束.
[3]编程:寻找回路
{1}首先从任意一个节点开始,利用深度优先搜索得到一个回路.对于每一个访问过的节点都删除访问过的边(具体手段就是删除相应的度数)。
{2}从上一次访问过的节点中找到一个度数不为0的节点,然后进行{1}的操作,最后将得到的新的访问路径拼接到原来的路径.
{3}反复进行{2},直到所有边都访问完.最后的路径就是欧拉回路.
#include "stdafx.h"
#include "图论ADT.h"
static int Indegree[Number] = {0};
static bool Isvisited[Number] = {false};
static int InitialNode;
int ReadGraphIndegree(Graph G)
{
int totaledges = 0;
int NumOdd = 0;
List L ;
for(int i = 0;i<=Number-1;i++)
{
L = G[i]->Next;
while(L!=NULL)
{
Indegree[i]++;
L = L->Next;
}
if (Indegree[i] %2 != 0)
{
NumOdd ++;
}
totaledges += Indegree[i];
}
if (NumOdd == 0)
{
puts("Eluer Cycle exists");
return totaledges/2;
}
else if (NumOdd == 2)
{
puts("Eluer route exists");
return totaledges/2;
}
else
{
puts("there is no route/cycle");
return 0;
}
}
List FindNewvertex(List Newvertex)
{
int x = Newvertex->Element;
Newvertex = Newvertex->Next;
while(Newvertex->Element != x)
{
if (Indegree[Newvertex->Element]>=2)
break;
Newvertex = Newvertex->Next;
}
return Newvertex;
}
void Depthfirstsearch(Graph G,List Newvertex,int & NumEdgevisited)
{
int start = Newvertex->Element;
int v = start,w;
List L = G[start]->Next;
while(L!=NULL&&Indegree[InitialNode]>0)//回路的条件
{
w = L->Element;
Newvertex->Element = w;
DeleteList(G[v],w);
DeleteList(G[w],v);
Indegree[v]--;
Indegree[w]--;
NumEdgevisited++;
Depthfirstsearch(G,Newvertex,NumEdgevisited);
if (Indegree[InitialNode]==0)//本次起始回路起始节点已经找到,正在退出递归
{
printf("%d ",w);
Insert_Behind(Newvertex,w);//将搜索到的路径拼接
}
L = L->Next;
}
}
List FindEulerloop(Graph G,int start)//寻找欧拉回路
{
int NumEdges = ReadGraphIndegree(G) ;
int NumEdgevisited = 0;
List head = (List)malloc(sizeof(Listrecord));
List Newvertex = head;
Newvertex->Element = start;
while(NumEdgevisited < NumEdges)
{
InitialNode = Newvertex->Element;//记录进去的节点,保证该节点所有边遍历完
Depthfirstsearch(G,Newvertex,NumEdgevisited);//进行一次深度优先搜索
printf("%d ",InitialNode);
Newvertex = FindNewvertex(Newvertex);//找到新的顶点
}
return head;
}