数据结构:图------>邻接矩阵与广度优先搜索的应用(C语言)

将近两个月没更新学习内容了(由于这学期转专业到计科事情比较多耽搁了)接下来会陆续更新数据结构相关的类容,同时这个假期将学习JAVA内容和准备一下蓝桥杯比赛(重心在java)

对于数据结构这门课程其实主要掌握的内容就:链表,顺序表,队列,栈,树,图中的(图的表示方法如邻接矩阵,邻接表),哈希等

图的应用一、其中大量使用了二级指针来动态开辟空间开充当二维数组,一级指针开辟空间空充当一维数组

广度优先搜索(BFS, Breadth First Search):
        类似于树的按层遍历从图中某个顶点v出发,先访问此顶点,接着依次访问v的所有邻接点,然后依次从这些邻接        点开始逐个逐个访问它们的邻接点
由近至远,以v为圆心逐步扩散访问其他顶点

 邻接矩阵:

1、编写程序,输入顶点个数,然后输入一个字符串表示顶点数据(顶点数据为字符);输入边的条数,然后以“a=b”的形式从输入多条无向边。读取上述输入,用邻接矩阵存储该无向图。然后,输出该图的广度优先搜索序列。例如,无向图如下:

那么应输入:

4

ABCD

4

A=B

A=D

B=C

C=D

输出为:

BFS:ABDC

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define INFINITY 32767 // 一个极大值,表示无穷
#define ElementType char
struct Graph {
    char* VertexList;  // 顶点数组,顶点数据类型为字符
    int** AdjacentMatrix;  // 邻接矩阵
    int VertexNum, EdgeNum; // 图的顶点数,边数
};
typedef struct Queue
{
    ElementType* Data;
    int MaxSize;
    int front;
    int rear;
}Queue;
//初始化队列
Queue* InitQueue(int Max)
{
    Queue* Q = (Queue*)malloc(sizeof(Queue));
    Q->MaxSize = Max;
    Q->Data = (ElementType*)malloc(sizeof(ElementType) * Max);
    Q->front = -1;
    Q->rear = -1;
    return Q;
}
//入队
void Push(Queue* Q, ElementType x)
{
    Q->Data[++(Q->rear)] = x;
}
//出队
ElementType Pop(Queue* Q)
{
    return Q->Data[++(Q->front)];
}
void BFS(struct Graph* G, char V)
{
    //建立辅助队列
    Queue* Q = InitQueue(G->VertexNum * (G->VertexNum - 1));
    //建立是否被访问数组,将其初始化为0表示未被访问
    int* visted = (int*)malloc(sizeof(int) * (G->VertexNum));
    for (int i = 0; i < G->VertexNum; i++)
    {
        visted[i] = 0;
    }
    //将最先访问节点入队
    Push(Q, V);
    //测试

    while (Q->front != Q->rear)//队列不为空
    {
        char w = Pop(Q);
        int index;//记录出队元素对应的下标
        for (int i = 0; i < G->VertexNum; i++)
        {
            if (G->VertexList[i] == w)
            {
                index = i;
            }
        }
        if (visted[index] == 1)
            continue;
        else
            visted[index] = 1;//将其标记为以访问,并代表w位置就是该元素位置
        printf("%c", w);
        for (int i = 0; i < G->VertexNum; i++)//访问visted中所有元素
        {
            if (visted[i] == 0 && G->AdjacentMatrix[index][i] == 1)
            {
                Push(Q, G->VertexList[i]);
            }
        }
    }

}
int Located(char VertexList[], char x)
{
    for (int i = 0; i < (int)strlen(VertexList); i++)
    {
        if (VertexList[i] == x)
            return i;
    }
    return -1;
}
struct Graph* InitGraph()
{
    int V, E;
    int x, y;
    printf("输入顶点数:\n");
    scanf("%d", &V);
    struct Graph* G = (struct Graph*)malloc(sizeof(struct Graph));
    //创建顶点数组
    G->VertexList = (char*)malloc(sizeof(char) * V);
    printf("输入顶点字符串:\n");
    scanf("%s", G->VertexList);//顶点数组
    G->VertexNum = V;//顶点个数
    printf("输入边的条数:\n");
    scanf("%d", &E);
    G->EdgeNum = E;
    //获取边,初始化二维数组
    G->AdjacentMatrix = (int**)malloc(sizeof(int*) * V);
    for (int i = 0; i < V; i++)
    {
        *(G->AdjacentMatrix + i) = (int*)malloc(sizeof(int) * V);
    }
    for (int i = 0; i < V; i++)
    {
        for (int j = 0; j < V; j++)
        {
            if (i == j)
            {
                G->AdjacentMatrix[i][j] = 0;
            }
            else
                G->AdjacentMatrix[i][j] = INFINITY;
        }
    }

    //获取边,
    printf("输入边的关系:\n");
    //gets(a);
    for (int i = 0; i < E; i++)
    {
        char a[3];
        scanf("%s", a);
        x = Located(G->VertexList, a[0]);
        y = Located(G->VertexList, a[2]);
        if (x != -1 && y != -1)
        {
            G->AdjacentMatrix[x][y] = 1;
            G->AdjacentMatrix[y][x] = 1;
        }

    }
    return G;
}
//打印邻接矩阵
void print(struct Graph* G)
{
    for (int i = 0; i < G->VertexNum; i++)
    {
        for (int j = 0; j < G->VertexNum; j++)
        {
            printf("%d\t", G->AdjacentMatrix[i][j]);
        }
        printf("\n");
    }
}
int main()
{
    struct Graph* G = InitGraph();
    printf("打印邻接矩阵\n");
    //打印邻接矩阵
    print(G);
    printf("输出为:\nBFS:");
    BFS(G, 'A');
    return 0;
}

运行结果为:

 代码块中有每一步的注释如有不明白的可以留言如果在能力范围类我会尽力解答

代码块可能可以优化但今天搞了很久就偷一下懒

最后:如果你是用VS来运行的话在代码的开头加上#define  _CRT_SECURE_NO_WARNINGS

但VS要注意的细节太多了(我学代码就是用他),但后来用了DVC++这个软件(这软件要注意的细节没这么多)推荐使用

接下来仪器还会更新图的内容:-->图的邻接表,表示法和拓扑排序的应用

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值