58-非连通图的遍历测试代码

非连通图的遍历测试代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#define MAXV 8
#define N 8

typedef struct ANode
{
    int adjvex;                 //记录某顶点的邻接点
    struct ANode *nextarc;      //指向下一条边节点的指针

} ArcNode; //边节点类型

typedef int Vertex;

typedef struct Vnode
{
    Vertex data;            //存储顶点的信息
    ArcNode *firstarc;      //指向第一个边节点

} VNode; //表头节点类型


typedef VNode AdjList[MAXV];

typedef struct
{
    AdjList adjlist;        //邻接表,这其实是一个数组(顺序表)
    int n,e;            //记录顶点个数n,边数e

} ALGraph; //完整的图邻接表类型


//图的定义:邻接矩阵
typedef struct MGRAPH{
    int n;                  //顶点数
    int e;                  //边数
    int deges[MAXV][MAXV];  //邻接矩阵
} MGraph;




/*
将邻接矩阵转换成邻接表
MGraph *g:表示邻接矩阵
*/
ALGraph *MatToList(MGraph *g)
{
    int i;
    int j;
    ArcNode *p = NULL;
    ALGraph *G = (ALGraph *)malloc(sizeof(ALGraph));

    //给所有头节点的指针域置初值
    for(i = 0; i < g->n; i++)
    {
        G->adjlist[i].firstarc = NULL;
    }

    //根据邻接矩阵建立邻接表中节点
    for(i = 0; i < g->n; i++)
    {
        for(j = g->n - 1; j >= 0; j--)
        {
            if(g->deges[i][j] != 0)
            {
                p = (ArcNode *)malloc(sizeof(ArcNode));
                p->adjvex = j;
                //采用头插法,插入邻接表
                p->nextarc = G->adjlist[i].firstarc;
                G->adjlist[i].firstarc = p;
            }
        }
    }
    G->n = g->n;
    G->e = g->e;

    return G;
}


//定义数组,算法执行前全置0
int visited[N] = {0};


void init_visited(int *arr)
{
    int i;
    if(arr == NULL)
    {
        return;
    }

    for(i = 0; i < N; i++)
    {
        *(arr + i) = 0;
    }
}


//G表示给定的图,采用邻接表存储
//v表示起始点
void DFS(ALGraph *G , int v)
{
    ArcNode *p = NULL;
    int w;

    if(G == NULL)
    {
        return;
    }

    //置为已访问标记
    visited[v] = 1;
    //输出被访问顶点的编号
    printf("%d\t" , v);
    //p指向顶点v的第一条边的头节点
    p = G->adjlist[v].firstarc;
    while(p != NULL)
    {
        //如果顶点w没有被访问过,则递归访问
        w = p->adjvex;
        if(visited[w] == 0)
        {
            DFS(G,w);
        }
        //如果已经访问过,p则指向下一条边的头节点
        p = p->nextarc;
    }
}


//G表示给定的图,采用邻接表存储
//v表示起始点
void BFS(ALGraph *G , int v)
{
    ArcNode *p;
    int w;
    int queue[MAXV],front=0,rear=0;

    //访问第一个顶点并入队,注意这里是采用的环形队列
    printf("%d\t",v);
    //标记为已访问
    visited[v]=1;
    rear=(rear+1)%MAXV;
    queue[rear]=v;

    //队列是否为空,否则取出队中未被访问的顶点
    while (front!=rear)
    {
        //取出队中顶点
        front=(front+1)%MAXV;
        w=queue[front];
        //获取邻接点(访问该顶点的所有未访问的邻接点并使之入队)
        p=G->adjlist[w].firstarc;
        while (p!=NULL)
        {   
            //这个邻接点是否已经访问
            if (visited[p->adjvex]==0)
            {
                //访问这个邻接点,并将该邻接点标记为已访问
                printf( "%d\t",p->adjvex);
                visited[p->adjvex]=1;

                //然后将邻接点入队
                rear=(rear+1)%MAXV;
                queue[rear]=p->adjvex;
            }
            //获取下一个邻接点
            p=p->nextarc;
        }
    }
}



//采用深度优先搜索遍历非连通无向图
void DFS1(ALGraph *G)
{
    int i;
    for (i=0;i<G->n;i++)
    {
        if (visited[i]==0)
        {
            DFS(G , i);
        }
    }

}


//采用广度优先搜索遍历非连通无向图
void BFS1(ALGraph *G)
{
    int i;
    for (i=0;i<G->n;i++)
    {
        if (visited[i]==0)
        {
            BFS(G , i);
        }
    }
}

//判断是否是连通图
int Connect(ALGraph *G)
{
    int i;
    //设置默认值
    int flag=1;
    //初始化visited数组
    for (i=0; i<G->n; i++)
        visited[i]=0;
    //这里以深度优先搜索为例 , 以顶点0为起始点开始遍历
    DFS(G,0);

    //判断所有顶点是否已经被访问
    for (i=0; i<G->n; i++)
        //如果有一个顶点没有被访问,说明这不是连通图,则更改flag标志
        if (visited[i]==0)
        {
            flag=0;
            break;
        }
        return flag;
}

int main(void)
{
    int i;
    int j;
    //result默认值为1,是连通图
    int result = 1;

    //A是一个非连通图
    int A[8][8]=
    {
        {0,1,0,1,0,0,0,0},
        {1,0,1,0,0,0,0,0},
        {0,1,0,1,1,0,0,0},
        {1,0,1,0,1,0,0,0},
        {0,0,1,1,0,0,0,0},
        {0,0,0,0,0,0,1,0},
        {0,0,0,0,0,1,0,1},
        {0,0,0,0,0,0,1,0},
    };

    ALGraph *ag = NULL;
    MGraph mg;
    mg.n = 8;
    mg.e = 9;

    for(i = 0; i < MAXV; i++)
    {
        for(j = 0; j < MAXV; j++)
        {
            mg.deges[i][j] = A[i][j];
        }
    }

    ag = MatToList(&mg);

    printf("\n");
    printf("深度优先搜索遍历非连通图:");
    //采用深度优先搜索遍历非连通无向图
    DFS1(ag);
    printf("\n\n");


    //在调用BFS1之前,先把visited数组初始化
    init_visited(visited);

    printf("广度优先搜索遍历非连通图:");
    //采用广度优先搜索遍历非连通无向图
    BFS1(ag);
    printf("\n\n");

    init_visited(visited);
    result = Connect(ag);
    printf("\n\n");

    if(result == 1)
    {
        printf("是连通图\n");
    }
    else
    {
        printf("非连通图\n");
    }

    return 0;
}

测试结果:

这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值