概述
离散数学实验:度数列判断简单图化、连通图、欧拉图、欧拉回路
可能存在问题,代码也不够简洁,希望有大家指正
/**************
By Vast Cosmic
2021.12.07
**************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define N 100
int m = 0; //点个数、元素个数
int martix[N][N]; //图矩阵
int d_cpy[N]; //度数列备份
int euler[N]; //欧拉路
int e; //边数
int main()
{
void maxsort(int *d, int n);
bool judge_gra(int *d,int n);
bool Havel(int *d, int n);
void gra_print(int *d, int n);
bool gra_connect(int *d);
bool judge_eula(int *d);
void find_euler(int m);
memset(martix, 0, sizeof(martix)); //图矩阵初始化
memset(euler, 0, sizeof(euler)); //欧拉路初始化
/*数列输入*/
int d[N] = {0};
printf("输入非负整数列元素个数:n");
scanf("%d", &m);
printf("输入序列n");
for (int i = 0; i < m;i++)
scanf("%d", &d[i]);
if(judge_gra(d, m)==1) //判断可图化
{
printf("n该数列可图化nn");
if(Havel(d, m)==1)
printf("该数列可简单图化,简单图如上n");
else
printf("n该数列不可简单图化n");
if(gra_connect(d_cpy)==1)
{
printf("n该图是连通图n");
if(judge_eula(d_cpy)==1)
{
printf("n该图是欧拉图n");
find_euler(m);
}
else
printf("n该图不是欧拉图n");
}
else
printf("n该图不是连通图n");
}
else
printf("n该数列不可图化n");
system("pause");
return 0;
}
/*判断可图化*/
bool judge_gra(int *d, int n)
{
int sum = 0;
while (n != 0)
{
sum += *d;
n -= 1;
d += 1;
}
d = &d[0];
if(sum%2==0)
return 1;
else
return 0;
}
/*判断简单图*/
bool Havel(int *d,int n)
{
void gra_print(int *d, int n);
void maxsort(int *d, int n);
void printf_gra(int *d,int n);
memset(d_cpy, 0, sizeof(d_cpy));
for (int i = 0; i < n;i++)
d_cpy[i] = d[i];
m = n; //记录简单图初始顶点的个数
while (judge_gra(d, n) == 1)
{
maxsort(d, n);
int control = d[0]; // 控制-1的循环个数
for (int i = 0; i < control; i++)
{
d[i] = d[i + 1] - 1;
if (d[i] < 0)
return 0;
}
int j = 1;
while (control + j != n)
{
d[control] = d[control + j];
j += 1;
}
n -= 1;
/* 全为0时退出 */
int flag = 0;
for (int i = 0; i < n; i++)
{
if (d[i] != 0)
flag = 1;
}
if (flag == 0)
break;
}
int sum = 0;
for (int i = 0; i < m;i++)
sum = sum + d_cpy[i];
e = sum / 2;
maxsort(d_cpy, m);
gra_print(d_cpy, m);
return 1;
}
void maxsort(int *d,int n) //sort form big one to small one
{
int temp = 0;
for (int i = 0; i < n;i++)
{
for (int j = 1; j < n; j++)
{
if (d[j-1] < d[j])
{
temp = d[j - 1];
d[j - 1] = d[j];
d[j] = temp;
}
}
}
}
void gra_print(int *d, int n)
{
int check_gra(int *d, int n); //简单图校验
int ra, rb; //两个随机数
int count = 0; //count来记录当前生成的度数
srand(time(0));
int sum = 0;
for (int i = 0; i < n;i++)
sum = sum + d[i]; //度数和
int check = 0;
while (check==0)
{
count = 0;
memset(martix, 0, sizeof(martix)); //图矩阵初始化
while (count < sum) //随机顶点顺序胜生成图
{
ra = rand() % n;
rb = rand() % n;
while (ra == rb) //避免生成自环
{
ra = rand() % n;
rb = rand() % n;
}
if (!martix[ra][rb]) //建立无向图邻接矩阵
{
martix[ra][rb] = martix[rb][ra] = 1;
count+=2;
}
}
if(check_gra(d_cpy, m) == 1)
check = 1;
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
printf(" %d ", martix[i][j]);
printf("n");
}
}
int check_gra(int *d, int n)
{
int n_gra_connect[N];
memset(n_gra_connect, 0, sizeof(n_gra_connect));
for (int i = 0; i < n;i++) //统计生成的图的每个点的度数
for (int j = 0; j < n;j++)
if(martix[i][j]==1)
n_gra_connect[i] += 1;
maxsort(n_gra_connect, n); //递减排序
int flag = 1; //判断生成的简单图的度数列是否与原度数列相同
for (int i = 0; i < n;i++)
if(d[i]!=n_gra_connect[i])
flag = 0;
return flag;
}
bool visit[N];
void DFS(int x, int *d)
{
visit[x] = true;
for (int i = 0; i<m; i++)
if (!visit[i] && martix[x][i]) //下个未搜索的i,且martix为1(可达),否则下一个i
DFS(i,d); //继续搜索,
}
bool gra_connect(int *d) //判断连通
{
void DFS(int x, int *d);
DFS(0, d);
for (int i = 0; i < m; i++)
if (!visit[i])
return 0;
return 1;
}
bool judge_eula(int *d_cpy)
{
int flag = 0;
for (int i = 0; i < m;i++)
{
if (d_cpy[i]%2==0 && d_cpy[i] != 0)
flag = 1;
else
{
flag = 0;
return 0;
}
}
if(flag==1)
return 1;
else
return 0;
}
void find_euler(int m) //m为边数
{
int euler_martix[m + 1][m + 1];
memset(euler_martix, 0, sizeof(euler_martix));
for (int i = 0; i < m;i++)
{
for (int j = 0; j < m;j++)
euler_martix[i + 1][j + 1] = martix[i][j]; //复制矩阵,便于表示顶点
}
int start = m, visit = start, tmp = 0; //从度数最小的点开始
while(true)
{
int flag1 = 0, flag_brige = 0;
for (int j = 1; j <= m; j++) //遍历该点与其它所有点的邻接关系
{
if (euler_martix[visit][j] >= 2) //找到第一条非桥
{
flag_brige++; //记录是否存在非桥
euler_martix[visit][j]--; //边是二元关系,两个点都要改变;包括了环的情况
euler_martix[j][visit]--;
printf(" %d,%d ", visit, j); //模拟走的道路
visit = j; //更新当前点
break; //找到就进入下一个点
}
if (euler_martix[visit][j] == 1 && flag1 == 0) //记录第一个与当前点存在一条边(不一定是割边)的点
{
flag1++;
tmp = j;
}
}
if (flag_brige == 0 && flag1 == 1) //走桥
{
euler_martix[visit][tmp]--;
euler_martix[tmp][visit]--;
printf("V%d->", visit);
visit = tmp;
}
if (flag_brige == 0 && flag1 == 0) //当矩阵为零矩阵时结束
break;
}
printf("V%dn",start);
}
最后
以上就是俏皮黑猫为你收集整理的离散数学实验:度数列判断简单图化、连通图、欧拉图、欧拉回路的全部内容,希望文章能够帮你解决离散数学实验:度数列判断简单图化、连通图、欧拉图、欧拉回路所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复