我是靠谱客的博主 俏皮黑猫,最近开发中收集的这篇文章主要介绍离散数学实验:度数列判断简单图化、连通图、欧拉图、欧拉回路,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

离散数学实验:度数列判断简单图化、连通图、欧拉图、欧拉回路 

可能存在问题,代码也不够简洁,希望有大家指正

/**************
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);
}

最后

以上就是俏皮黑猫为你收集整理的离散数学实验:度数列判断简单图化、连通图、欧拉图、欧拉回路的全部内容,希望文章能够帮你解决离散数学实验:度数列判断简单图化、连通图、欧拉图、欧拉回路所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部