离散数学实验报告 实验3 欧拉路的确定
一、实验目的
理解欧拉图的概念,掌握欧拉通/回路的判定方法。
二、实验内容
输入一个无向简单图的邻接矩阵,判定该图是否含有欧拉通/回路。若有,请给出一条欧拉通/回路。
三、实验环境
采用C或C++语言为编程语言实现。
四、实验过程
- 算法分析
(1) 无向图G是欧拉图当且仅当G是连通的且没有奇度顶点。
(2) 无向图G是半欧拉图当且仅当G是连通的且恰有两个奇度顶点。
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<string.h>
#define N 100
struct stacks
{
int top;
int node[100];
}s;
int n, a[N][N],b[N];
bool visit[N];
int ans[N], cnt = 0; //记录欧拉路的路径,路径数
void show();
void DFS(int);
bool judge_connect(); //判断是否连通
void judge_euler(); //判断是否是欧拉回路
void Fleury(int x);
void answer();
int main()
{
memset(a, 0, sizeof(a));
//memset(ans, 0, sizeof(ans));//使用循环可使用次代码重置数组为0
printf("请输入顶点个数(小于等于100):\n");
scanf_s("%d", &n);
if (n < 0 || n>100)
{
printf("请输入小于等于100的数!\n");
exit(0);
}
for (int i = 0; i < n; i++)
for (int j = i + 1; j < n; j++)
{
a[i][j] = 0 + rand() % 2; //随机生成无向图
a[j][i] = a[i][j];
}
show();
if (judge_connect())
{
printf("该随机生成的图是连通图\n");
judge_euler();
}
else
{
printf("该随机生成的图不是连通图\n");
}
return 0;
}
void DFS(int x)
{
visit[x] = true;
for (int i = 0; i < n; i++)
if (!visit[i] && a[x][i])
DFS(i);
}
bool judge_connect()
{
DFS(0);
for (int i = 0; i < n; i++)
if (!visit[i])
return false;
return true;
}
void judge_euler()
{
int num = 0, start = 0, degree; // 奇度顶点个数, 欧拉路的起点, 每个顶点的度
//如果存在奇度顶点,则从奇度顶点出发,否则从0出发
for (int i = 0; i < n; i++)
{
degree = 0;
for (int j = 0; j < n; j++)
degree += a[i][j];
if (degree % 2)
{
start = i;
num++;
}
}
//无向图具有一条欧拉路,当且仅当G是连通的,且有0个或2个奇数度结点
if (num == 0 || num == 2)
{
Fleury(start);
//欧拉路径的头和尾相等,则说明欧拉路是回路
if (ans[0] == ans[cnt - 1])
printf( "该图为欧拉图,欧拉回路为: ");
else
printf ( "该图为半欧拉图,欧拉通路为: ");
answer();
}
else
{
printf("非(半)欧拉图\n");
}
}
void DFS2(int x) //深度优先遍历
{
s.top++;
s.node[s.top] = x;
for (int i = 0; i < n; i++)
{
if (a[i][x] > 0)
{
a[i][x] = 0; //删边操作
a[x][i] = 0;
DFS2(i);
break;
}
}
}
void Fleury(int x) //Fleury算法
{
int b;
s.top = 0;
s.node[s.top] = x; //起点入栈
while (s.top >= 0)
{
b = 0;
for (int i = 0; i < n; i++)
{
if (a[s.node[s.top]][i] > 0)
{
b = 1;
break;
}
}
if (b == 0) //如果没有可扩展的点,则记录下该点并将其出栈
{
ans[cnt++] = s.node[s.top] + 1;
s.top--;
}
else //如果有,则将其出栈并继续搜索
{
s.top--;
DFS2(s.node[s.top + 1]);
}
}
printf("\n");
}
void answer() //输出答案
{
for (int i = 0; i < cnt; i++)
printf("%d ", ans[i]);
printf("\n");
}
void show() //输出随机生成的无向图关系矩阵
{
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
printf("%d\t", a[i][j]);
}
printf("\n");
}
}