【图的深度优先遍历C语言版】

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include<string.h>
#include<stdlib.h>
#define OK 1
#define ERROR 0
#define MAX_VERTEX 100
#define VISITED 1
#define UNVISITED 0
//图的类型枚举
typedef enum
{
    DG,//有向图
    UDG,//无向图
    DN,//有向网
    UDN//无向网
}Graphkind;
//设置顶点的数据类型为字符串型-使用时记得
typedef char* VerTexType;
//设置权值类型为整数类型
typedef int ArcType;
//返回的状态类型
typedef int Status;
//保存每个顶点的访问状态 0-未访问 1-已访问
int visitdfs[MAX_VERTEX];
//图的邻接矩阵存储表示
typedef struct
{
    VerTexType verTexs[MAX_VERTEX];//顶点数组
    ArcType arcs[MAX_VERTEX][MAX_VERTEX];//邻接矩阵(权数组)
    int verTexCount;//图的顶点数
    int arcCount;//图的边数/弧的数
    Graphkind kind;//图的类型
}MathrixGraph;
//返回某个顶点在顶点集合中的下标(从0开始),不存在返回-1
int LocateVex(MathrixGraph* G, VerTexType vex)
{
    int index = 0;
    while (index < G->verTexCount)
    {
        if (strcmp(G->verTexs[index], vex) == 0)
            break;
        index++;
    }
    return index == G->verTexCount ? -1 : index;
}
//使用邻接矩阵表示法创建无向图
/*
无向图的特点:
1.无向图的邻接矩阵是对称的
2.顶点的度=第一行(列)中1的个数
*/
Status CreateUDG(MathrixGraph* G)
{
    G->kind = UDG;//设置当前创建图的类型为无向图
    printf("请输入无向图的定的点数:");
    scanf("%d", &G->verTexCount);
    printf("请输入边的数量:");
    scanf("%d", &G->arcCount);
    printf("依次输入顶点信息\n");
    int i;
    int j;
    for (i = 0; i < G->verTexCount; i++)
    {
        G->verTexs[i] = (VerTexType)malloc(sizeof(char) * 10);
        printf("顶点%d: ",i+1);
        scanf("%s", G->verTexs[i]);
    }
    //初始化邻接矩阵,所有边的权值设置为0
    for (i = 0; i < G->verTexCount; i++)
    {
        for (j = 0; j < G->verTexCount; j++)
        {
            G->arcs[i][j] = 0;
        }
    }
    printf("请输入顶点和邻接顶点的信息,构建邻接矩阵\n");
    for (i = 0; i < G->arcCount ; i++)
    {
        VerTexType vex1 = (VerTexType)malloc(sizeof(char) * 10);
        VerTexType vex2 = (VerTexType)malloc(sizeof(char) * 10);
        printf("顶点:");
        scanf("%s", vex1);
        printf("邻接点:");
        scanf("%s", vex2);
        //分别获得两个顶点在顶点数组中的坐标
        int x = LocateVex(G, vex1);
        int y = LocateVex(G, vex2);
        if (x == -1 || y == -1)
            return ERROR;
        G->arcs[x][y] = 1;
        G->arcs[y][x] = G->arcs[x][y];
        free(vex1);
        free(vex2);
    }
    return OK;
}
//使用邻接矩阵表示法创建有向图
/*
有向图的特点:
1.有向图的邻接矩阵有可能是不对称的
2.顶点的出度=第i行元素之和;顶点的入度=第i列元素之和
3.顶点的度=第i行元素之和+第i列元素之和
*/
Status CreateDG(MathrixGraph* G)
{
    G->kind = DG;//设置当前创建图的类型为有向图
    printf("请输入有向图的定的点数:");
    scanf("%d", &G->verTexCount);
    printf("请输入边的数量:");
    scanf("%d", &G->arcCount);
    printf("依次输入顶点信息\n");
    int i;
    int j;
    for (i = 0; i < G->verTexCount; i++)
    {
        G->verTexs[i] = (VerTexType)malloc(sizeof(char) * 10);
        printf("顶点%d: ", i+1);
        scanf("%s", G->verTexs[i]);
    }
    //初始化邻接矩阵,所有边的权值设置为0
    for (i = 0; i < G->verTexCount; i++)
    {
        for (j = 0; j < G->verTexCount; j++)
        {
            G->arcs[i][j] = 0;
        }
    }
    printf("请输入顶点和邻接顶点的信息,构建邻接矩阵\n");
    for (i = 0; i < G->arcCount; i++)
    {
        VerTexType vex1 = (VerTexType)malloc(sizeof(char) * 10);
        VerTexType vex2 = (VerTexType)malloc(sizeof(char) * 10);
        printf("顶点:");
        scanf("%s", vex1);
        printf("邻接点:");
        scanf("%s", vex2);
        //分别获得两个顶点在顶点数组中的坐标
        int x = LocateVex(G, vex1);
        int y = LocateVex(G, vex2);
        if (x == -1 || y == -1)
            return ERROR;
        G->arcs[x][y] = 1;
        //G->arcs[y][x] = G->arcs[x][y];//有向图的邻接矩阵有可能不对称
        free(vex1);
        free(vex2);
    }
}
//邻接矩阵深度优先遍历
void DFSTraverse_AMG(MathrixGraph G)
{
    void DFS_AMG(MathrixGraph G, int index);
    //初始化状态数组
    int i = 0;
    for (i = 0; i < G.verTexCount; i++)
    {
        visitdfs[i] = UNVISITED;//初始状态设置为未访问
    }
    //DFS遍历
    for (i = 0; i < G.verTexCount; i++)
    {
        if (!visitdfs[i])//如果某个顶点未访问
        {
            //调用遍历函数
            DFS_AMG(G, i);
        }
    }
}
//深度优先搜索的核心算法,index为深度搜索的某个顶点下标
void DFS_AMG(MathrixGraph G,int index)
{
    printf("->%s", G.verTexs[index]);//访问当前顶点
    visitdfs[index] = VISITED;//更改当前顶点的访问状态
    int i;
    for (i = FirstAdjMAXVex_AMG(G, G.verTexs[index]); i; i= SecondjVex_AMG(G,G.verTexs[index],G.verTexs[i]))
    {
        if (!visitdfs[i])
        {
            DFS_AMG(G, i);//如果没有访问过就继续递归调用搜索
        }
    }
}
//返回顶点vex所在行中第一个邻接点的下标
int FirstAdjMAXVex_AMG(MathrixGraph G, VerTexType vex)
{
    int i = LocateVex(&G, vex);//找到顶点vex在顶点数组中的下标
    if (i == -1)
        return ERROR;
    int defaultWeight;//默认权重
    defaultWeight = G.kind <= 1 ? 0 : INT_MAX;//图/网
    //搜索图的邻接矩阵中与顶点vex的第一个邻接点的下标
    for (int j = 0; j < G.verTexCount; j++)
    {
        if (G.arcs[i][j] != defaultWeight)
        {
            return j;
        }
    }
    return 0;
}
//返回与顶点vex1邻接的另一个邻接点(除vex2)的下一个邻接点,没有就返回-1
int SecondjVex_AMG(MathrixGraph G, VerTexType vex1, VerTexType vex2)
{
    int index1 = LocateVex(&G, vex1);
    int index2 = LocateVex(&G, vex2);
    if (index1 == -1 || index2 == -1)
        return -1;
    int defaultWeight;
    defaultWeight = G.kind <= 1 ? 0 : INT_MAX;
    for (int i = index2 + 1; i < G.verTexCount; i++)
    {
        if (G.arcs[index1][i] != defaultWeight)
        {
            return i;
        }
    }
    return 0;
}
void TestMatrixUDG()
{
    int i;
    int j;
    MathrixGraph G;
    //创建无向图
    Status status = CreateUDG(&G);
    //创建有向图
    //Status status = CreateDG(&G);
    if (status == ERROR)
    {
        printf("创建图失败,请检查后重试\n");
    }
    printf("打印图的邻接矩阵\n");
    printf("\t");
    for (i = 0; i < G.verTexCount; i++)
    {
        printf("\t%s", G.verTexs[i]);
    }
    printf("\n");
    for (i = 0; i < G.verTexCount; i++)
    {
        printf("\t%s", G.verTexs[i]);
        for (j = 0; j < G.verTexCount; j++)
        {
            printf("\t%d", G.arcs[i][j]);
        }
        printf("\n");
    }
    printf("\n深度优先遍历\n");
    DFSTraverse_AMG(G);
}
int main()
{
    TestMatrixUDG();
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值