欧拉路径的定义:对于无向图来说,欧拉路径就是通过每条边有且只有一次,如果遍历的起始点和终止点都是一个顶点的话,那么就说这个图存在欧拉环。
上图中有三个例子,分别是欧拉路径和欧拉环,以及非欧拉路径。那么怎么来判断一个图中是否含有欧拉路径或者欧拉环呢。首先回想一下图的定义,图中有v个顶点,那么着v个顶点中有0个或者两个或者两个以上的顶点度数为奇数。接下来,求欧拉路径就相当于用笔画一个图,笔可以经过每一个顶点,画出某一条边有且只有一次,而不用离开纸张的表面。
如果一个图中含有一条欧拉路径,那么它就被称为半欧拉的。先看看第一幅图,含有欧拉路径图的特点,除了顶点0和顶点4之外,其他的顶点的度数都是偶数,这这个图中是2.
看第二幅图,所有的顶点的度数都是偶数,之后第三幅图,有4个顶点的度数是奇数。那么就能得到非欧拉路径和欧拉路径的区别就是非欧拉路径有超过2个以上的顶点度数为奇数。
给定欧拉环的算法:
1,对于所有度数不为0的顶点和他们之间的边组成的图进行检验,看看是否他们组成的图是连通的,如果所有顶点的度数都为0,那么我们可以说这个图是含有欧拉路径的。
2,判断所有的顶点的度数是否为偶数。
欧拉路径算法:
1,对于所有度数不为0的顶点和他们之间的边组成的图进行检验,判断他们组成的图是否是连通的。
2,对于所有第一步检验的顶点,判断他们之中有奇数度数的个数,如果超过2个以上度数为奇数,那么此图不含欧拉路径。
下面是代码:
#include<iostream> #include<list> using namespace std; class Graph { int vexNum; list<int>* adjacents; public: Graph(int _vexNum); ~Graph(); void addEdge(int v, int w); void DFSUtil(int v, bool* visited); bool isConnected(); int isEulerian(); }; Graph::Graph(int _vexNum) { vexNum = _vexNum; adjacents = new list<int>[vexNum]; } Graph::~Graph() { delete []adjacents; } void Graph::addEdge(int v, int w) { adjacents[v].push_back(w); adjacents[w].push_back(v); } void Graph::DFSUtil(int v, bool *visited) { visited[v] = true; list<int>::iterator iter; for (iter = adjacents[v].begin(); iter != adjacents[v].end(); iter++) if (false == visited[*iter]) DFSUtil(*iter, visited); } bool Graph::isConnected() { int v; bool* visited = new bool[vexNum]; for (v = 0; v < vexNum; v++) visited[v] = false; for (v = 0; v < vexNum; v++) if (0 != adjacents[v].size()) break; if (v >= vexNum) return true; DFSUtil(v, visited); for (v = 0; v < vexNum; v++) if (false == visited[v] && adjacents[v].size() > 0) return false; return true; } int Graph::isEulerian() {// 0 represents non eulerian, 1 represents eulerian path, 2 represents eulerian cycle bool rst = isConnected(); if (!rst) return 0; int v; int odd = 0; for (v = 0; v < vexNum; v++) if (adjacents[v].size() & 0x01) odd++; if (odd > 2) return 0; return odd ? 1 : 2; } void test(Graph& g) { int rst = g.isEulerian(); if (0 == rst) cout << "there is no eulerian path or cycle" << endl; else if (1 == rst) cout << "there is a eulerian path" << endl; else cout << "there is a eulerian cycle" << endl; } int main(int argc, char* argv[]) { Graph g1(5); g1.addEdge(1, 0); g1.addEdge(0, 2); g1.addEdge(2, 1); g1.addEdge(0, 3); g1.addEdge(3, 4); test(g1); Graph g2(5); g2.addEdge(1, 0); g2.addEdge(0, 2); g2.addEdge(2, 1); g2.addEdge(0, 3); g2.addEdge(3, 4); g2.addEdge(4, 0); test(g2); Graph g3(5); g3.addEdge(1, 0); g3.addEdge(0, 2); g3.addEdge(2, 1); g3.addEdge(0, 3); g3.addEdge(3, 4); g3.addEdge(1, 3); test(g3); // Let us create a graph with 3 vertices // connected in the form of cycle Graph g4(3); g4.addEdge(0, 1); g4.addEdge(1, 2); g4.addEdge(2, 0); test(g4); // Let us create a graph with all veritces // with zero degree Graph g5(3); test(g5); cin.get(); return 0; }