欧拉回路

摘要:欧拉回路的基本定义是从一个起点出发,遍历所有的边最后回到起点.欧拉通路则不要求回到初始点.

基本思路:

[1]首先给出两个定理,如果一个无向图存在欧拉回路,那么它一定每一个节点的度数都是偶数.这很容易理解,假如某个节点的出度与入度不等,那么终究有某次访问该点导致不能出去.

[2]如果一个无向图存在欧拉通路,要么它每个节点的度数都是偶数,要么存在两个节点的度数是奇数.而且如果有两个节点是奇数,那么该回路只能从一个奇数节点出发,到另一个节点结束.

[3]编程:寻找回路

{1}首先从任意一个节点开始,利用深度优先搜索得到一个回路.对于每一个访问过的节点都删除访问过的边(具体手段就是删除相应的度数)。

{2}从上一次访问过的节点中找到一个度数不为0的节点,然后进行{1}的操作,最后将得到的新的访问路径拼接到原来的路径.

{3}反复进行{2},直到所有边都访问完.最后的路径就是欧拉回路.

欧拉回路_第1张图片
欧拉回路_第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;
}

你可能感兴趣的:(欧拉回路)