`
evasiu
  • 浏览: 169487 次
  • 性别: Icon_minigender_2
  • 来自: 广州
博客专栏
Fa47b089-e026-399c-b770-017349f619d5
TCP/IP详解卷一>阅读...
浏览量:12549
社区版块
存档分类
最新评论

图论--寻找欧拉回路

阅读更多

首先介绍一下fleury算法。

大概描述是这样子的:

(1)设图G的顶点集为V(G), 从中任取一个顶点V0,令P0 = V0;

(2)设Pi=v0e1v1e2...eivi已经行遍,按下面的方面来从E(G)-{e1, e2, ..., ei}中选取ei+1:

    (2.1)ei+1与vi相关联,也就是,从vi射出。

    (2.2)除非无别的边可供选择,否则ei+1不应该为Gi=G-{e1, e2, ..., ei}中的桥。所谓的桥,是指当把它从图中删除时,原本连通的图不连通了。

(3)当(2)不能再进行时,算法停止。

 

算法的思想我是理解的,不过我也没有实现。在网上看到一个用递归实现的算法,很简洁,可是我不确定它是否是fleury算法,因为我没有看到有关边的选择是如何优先避开桥的。先贴这里吧。

 

void dfs( int** g, int vnum, int id, int* s, int* front ){
	int i;
	s[++(*front)] = id;
	for( i=0; i<vnum; i++ ){
		if( g[i][id]>0 ){
			g[i][id] --;
			g[id][i] --;
			dfs(g, vnum, i, s, front);
			break;
		}
	}
}
		
void eulerPath( int** g, int vnum, int x ){
	int* stack = (int*)malloc( sizeof(int)*vnum );
	int front = 0;
	stack[front] = x;
	int i, b;
	while( front>=0 ){
		b = 0;
		for( i=0; i<vnum; i++ ){
			if( g[stack[front]][i] > 0 ){
				b = 1;
				break;
			}
		}
		if( b == 0 ){
			printf( "%d ", stack[front] );
			front -- ;
		}else{
			front--;
			dfs( g, vnum, stack[front+1],stack, &front );
		}
	}
	printf( "end of eulerPath\n" );
	free( stack );
}

 递归得很厉害。我又想不大明白。于是就自己照着书本的那个证明,做了如下的画圈圈的算法。

 

typedef struct node{
	int id;
	struct node* next;
	struct node* prev;
}pathNode;

typedef struct {
	struct node* head;
	struct node* current;
}path;

//this function finds the euler route and return its head
path* eulerCircle( int** g, int* indgr, int num ){
	path* p = (path*)malloc( sizeof(path) );
	p->head = (pathNode*)malloc( sizeof( pathNode ) );
	(p->head)->id = 0;
	(p->head)->prev = NULL;
	(p->head)->next = NULL;
	//without lose of generality, we start our search from v0
	p->current = p->head;
	int i;
	int count=0, top=0;
	while( count < num ){
		path* ptmp = (path*)malloc( sizeof(path) );
		ptmp->head = (pathNode*)malloc( sizeof( pathNode ) );
		ptmp->head->id = -1;
		ptmp->head->prev = NULL;
		ptmp->head->next = NULL;
		ptmp->current = ptmp->head;
		int c=top;
		//this while loop is to find a loop in the graph
		while(1){
			for( i=0; i<num; i++ ){
				if( g[c][i] > 0 ){
					g[c][i]--;
					g[i][c]--;
					indgr[c]--;
					indgr[i]--;
					if( indgr[c] == 0 )
						count++;
					if( indgr[i] == 0 )
						count++;
					c = i;
					ptmp->current->id = i;
					pathNode* t = (pathNode*)malloc( sizeof(pathNode) );
					t->id = -1;
					t->next = NULL;
					ptmp->current->next = t;
					t->prev = ptmp->current;
					ptmp->current = t;
					break;
				}
			}
			if( c == top )
				break;
		}
		pathNode* t = ptmp->current;
		pathNode* tt = p->current->next;
		//find a new circle from vertex top
		if( t->prev != NULL ){
			ptmp->current = ptmp->current->prev;
			ptmp->current->next = NULL;
			free( t );
			p->current->next = ptmp->head;
			ptmp->head->prev = p->current;
			p->current = ptmp->current;
			p->current->next = tt;
			if( tt != NULL )
				tt->prev = p->current;
		}else{
			free( t );
			free( ptmp );
		}
		//modify the value of top, to start a new circle
		tt = p->current;
		while( tt != NULL ){
			if( indgr[tt->id] > 0 ){
				top=tt->id;
				p->current = tt;
				break;
			}
			tt = tt->prev;
		}

	}
	return p;
}

//this function prints the path we've just found
void printPath( path* p ){
	if( p == NULL ){
		printf( "NULL pointer\n" );
		return ;
	}
	pathNode* head = p->head;
	pathNode* t = head;
	for( t=head; t!=NULL; t=t->next )
		printf( "%d->", t->id );
	printf( "\n" );
}

//this function frees the path we constructed in eulerCircle
void freePath( path* p ){
	if( p == NULL ){
		printf( "NULL pointer\n" );
		return ;
	}
	
	pathNode* head = p->head;
	pathNode* t = head;
	while( head != NULL ){
		t = head->next;
		free(head);
		head = t;
	}
}

 

大概思想是这样子的:首先找到一个圈,将圈上的边去掉,此时图中顶点的入度依然为偶数(或者为0),从刚才的圈中任找一个入度不为0的顶点(肯定至少存在一个,不然图就是不连通的了),再找一个圈,也就是说,像原先0->1->2->0的圈,假如从2出发有2->5->6->4->2的圈,那么现在就可以形成一个0->1->2->5->6->4->2->0的圈了。所以其实结果我的主要任务就变成维护好这个列表了,呵呵。。。如果用高级一点的数据结构的话,是不需要多少代码的。。哈哈。这个算法就是我用在中国邮递员里面的算法。

 

我还是希望有个人能跟我讲讲上面那个递归的算法。。也或许是我对深搜还没有真正透彻的理解吧。

分享到:
评论

相关推荐

    图论- 图的遍历- 欧拉通路与欧拉回路问题.rar

    在城市规划中,寻找欧拉回路有助于设计无重复的道路环线。 综上所述,图论中的欧拉通路与欧拉回路是理解图的结构和性质的重要工具,它们在理论研究和实际应用中都具有重要价值。通过深入学习和掌握这些概念,我们...

    2022级图论-欧拉回路和最短路-题解

    综上所述,2022级的图论课程涵盖了基本的图论概念,包括欧拉回路的探索以及寻找图中顶点间最短路径的算法。学习者还将接触到链式前向星和邻接表这两种有效的图数据结构,并掌握C++中`pair`的使用,这些都是解决实际...

    20151910042-刘鹏-AG实验05-欧拉图判断与寻找欧拉回路1

    《欧拉图判断与寻找欧拉回路》的实验报告主要关注的是图论中的一个重要概念——欧拉图。欧拉图是指一个图中每条边恰好被包含在一条闭合路径中,即存在一个经过图中所有边的路径,而没有重复的顶点。这个路径称为欧拉...

    图论——欧拉路径和欧拉回路

    本篇将深入探讨图论中的一个重要概念——欧拉路径与欧拉回路。 **一、欧拉路径** 欧拉路径是图论中的一个经典概念,由瑞士数学家欧拉提出。在一个无向图(边没有方向)中,如果可以从一个顶点出发,沿着边经过图中...

    哈尔滨工业大学图论-总结-CSDN下载

    1. 欧拉路径与欧拉回路:在一个无环且无奇数度顶点的无向图中,存在一条经过所有边的路径(欧拉路径),如果这个图还包含一个起点和终点相同的路径,那么这个图有欧拉回路。 2. 弗洛伊德-沃瑟斯坦定理:提供了计算有...

    数学建模-图论-总结.zip

    若起点和终点相同,则为欧拉回路。 9. **哈密顿路径/回路**: 若一条路径经过了图中每个顶点且仅经过一次,称为哈密顿路径;若起点和终点相同,则为哈密顿回路。 **图论算法** 1. **最短路径问题**: 如Dijkstra...

    算法-欧拉回路(HDU-1878)(包含源程序).rar

    该算法首先遍历图以标记顶点的遍历顺序,然后逆序遍历这些顶点,通过第二次深度优先搜索来寻找欧拉回路。另一种算法是霍夫曼桥算法,即Hoffman-Peterson算法,它同样基于深度优先搜索,并且更直接地寻找欧拉回路。 ...

    图论(回路矩阵,欧拉道路,最佳匹配)

    欧拉道路和欧拉回路是图论中的经典概念。欧拉道路是图中一个起点和终点不同的路径,沿途经过每条边恰好一次;而欧拉回路则是从一个节点出发,沿着边走,最后回到出发点,且每条边恰好走过一次。寻找欧拉道路或回路...

    欧拉回路计算

    欧拉回路是图论中的一个重要概念,它指的是在无向图或有向图中,一个从某点出发,经过图中每条边恰好一次,最后又回到起点的路径。在学习数据结构的过程中,理解并实现欧拉回路的算法是一项基础而关键的任务。这个...

    实验4-图的生成及欧拉回路的确定1

    实验目标是学习和掌握图的表示方法、欧拉图的概念以及如何寻找欧拉回路。在这个实验中,学生将使用离散数学的知识来处理无向图,并通过编程实现欧拉路径的搜索。 1. **图的生成** - **邻接矩阵**:为了存储图,...

    欧拉回路输出路径

    5. **欧拉回路算法**:从符合条件的顶点开始,递归地寻找欧拉回路,并输出结果。 #### 关键函数 - `add` 函数用于添加边到邻接表。 - `cmp` 函数用于比较两个单词,确保按照字典序排序。 - `find` 函数用于并查...

    欧拉回路题集

    - **题目描述**:在一个混合图(既有有向边也有无向边)中寻找欧拉回路。 - **解题思路**:将有向边和无向边分别处理,最后合并求解。 - **数据结构**:分别用邻接表表示有向图和无向图。 6. **【HDU】3472 ...

    有向图的欧拉回路

    如果这些条件都满足,就调用`Fleury`算法寻找欧拉回路。 总结来说,判断有向图是否存在欧拉回路需要考虑以下几个关键点: 1. 图是否连通。 2. 图中是否存在奇度点。 3. 使用Fleury算法构造可能的欧拉回路。 在实际...

    3.仇荣琦《欧拉回路性质与应用探究》1

    解决问题的关键在于理解欧拉回路的性质,例如,如何通过顶点的度数判断图的欧拉性,以及如何构建或寻找欧拉回路。在图的表示上,通常使用邻接矩阵或邻接表来存储图的信息,然后通过算法来探索是否存在欧拉回路。 ...

    21-集合论与图论-期末1

    如果一个图可以通过一次旅行遍历所有边而且回到起点,那么它是欧拉回路,而欧拉图可能包含一个或多个欧拉回路。 9. **点独立数、边独立数、点覆盖数、边覆盖数**:点独立数是图中最大的不相邻顶点集合大小;边独立...

    构造欧拉图与找欧拉回路的算法

    2. **DFS with Backtracking**:深度优先搜索也可以用于寻找欧拉回路,通过递归地探索每个可能的分支,直到找到一个闭合路径。当遇到死胡同时,回溯到上一个决策点,尝试另一条边。 在实际应用中,欧拉图的概念和...

    图论- 生成树- 生成树计数.rar

    此外,生成树计数还与图的其他属性紧密相关,如欧拉路径、哈密顿回路、最短路径等问题。它与图的矩阵表示(如邻接矩阵和关联矩阵)和图的多项式(如图的生成函数)也有关联,这些都为深入研究图的结构提供了工具。 ...

    有无向欧拉回路(邻接阵) template

    本文主要涉及图论中的一个经典问题——欧拉路径与欧拉回路的判定及其寻找算法,并着重介绍如何利用邻接矩阵来实现这一过程。 ### 欧拉路径与欧拉回路 在图论中,欧拉路径是指一条通过图中每条边恰好一次的路径,而...

    oula.rar_欧拉回路_欧拉图

    在寻找欧拉回路时,我们可以从任意顶点开始,沿着边进行DFS,如果当前路径形成一个环且环中所有顶点的度数都减为零,那么就找到了一个欧拉回路。 在具体实现DFS寻找欧拉回路时,可以采用递归或栈的方式来操作。首先...

Global site tag (gtag.js) - Google Analytics