栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

C语言数据结构学习笔记(18)-无向网图的DFS和BFS遍历及最小生成树Prim算法

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

C语言数据结构学习笔记(18)-无向网图的DFS和BFS遍历及最小生成树Prim算法


# include
# include
# define MAX_VEX 10//最大顶点个数
# define INF 0x3f3f3f3f//无穷大
# define SIZE 5//顶点信息最大字符串个数+1
typedef char VertexType[SIZE];
typedef int EdgeType;
typedef struct{
    VertexType vexs[MAX_VEX];//顶点数组
    EdgeType arc[MAX_VEX][MAX_VEX];//边表
    int vexNum, edgeNum;//图中顶点和边的个数
}MGraph;//无向网图邻接矩阵
struct minEdge{
    int adjvex;//顶点下标
    int lowcost;//最小权值
}minEdge[MAX_VEX];//创建最小权值边数组

bool visited[MAX_VEX];//访问标志数组
void CrateMGraph(MGraph * G);//创建无向网图
void PrintMGraph(MGraph G);//打印邻接矩阵
void DFSTraverse(MGraph G);//深度优先遍历
void DFS(MGraph G, int i);//深度优先递归
void BFSTraverse(MGraph G);//广度优先遍历
void Prim(MGraph G, int start);//最小生成树-Prim算法

int main(void)
{    
    int start;
    MGraph G;
    CrateMGraph(&G);
    PrintMGraph(G);
    DFSTraverse(G);
    BFSTraverse(G);
    printf("请输入最小生成树的起始顶点:");
    scanf("%d", &start);
    Prim(G, start);
    system("pause");
    return 0;
}
//创建无向网图
void CrateMGraph(MGraph * G)
{
    int i, j, k, w;
    printf("请输入顶点和边的个数:");
    scanf("%d %d", &G->vexNum, &G->edgeNum);
    for(i = 0; i < G->vexNum; i++)
    {
        printf("请输入第%d个顶点的信息:", i+1);
        scanf("%s", &G->vexs[i]);
    }
    for(i = 0; i < G->vexNum; i++)
        for(j = 0; j < G->vexNum; j++)
            G->arc[i][j] = INF;
    for(k = 0; k < G->edgeNum; k++)
    {
        printf("请输入第%d条边(Vi, Vj)两个顶点的下标及权值:", k+1);
        scanf("%d %d %d", &i, &j, &w);
        G->arc[i][j] = w;
        G->arc[j][i] = G->arc[i][j];
    }
}
//打印邻接矩阵
void PrintMGraph(MGraph G)
{    
    int i, j;
    for(i = 0; i < G.vexNum; i++)
        printf("t%s", G.vexs[i]);
    printf("n");
    for(i = 0; i < G.vexNum; i++)
    {
        printf("%st", G.vexs[i]);
        for(j = 0; j < G.vexNum; j++)
        {    
            if(G.arc[i][j] == INF)
                printf("∞t");
            else
                printf("%dt", G.arc[i][j]);
        }
        printf("n");
    }
}
//深度优先遍历
void DFSTraverse(MGraph G)
{    
    int i;
    for(i = 0; i < G.vexNum; i++)
        visited[i] = false;
    printf("nDFS:t");
    for(i = 0; i < G.vexNum; i++)
    {
        if(!visited[i])
            DFS(G, i);
    }
    printf("n");
}
//深度优先递归
void DFS(MGraph G, int i)
{    
    int j;
    visited[i] = true;
    printf("%st", G.vexs[i]);
    for(j = 0; j < G.vexNum; j++)
    {
        if(!visited[j] && G.arc[i][j] != INF)
            DFS(G, j);
    }
}
//广度优先遍历
void BFSTraverse(MGraph G)
{    
    int i , j;
    for(i = 0; i < G.vexNum; i++)
        visited[i] = false;
    int Queue[MAX_VEX];//队列存放顶点对应下标
    int front = 0, rear = 0;//队首队尾下标
    printf("BFS:t");
    for(i = 0; i < G.vexNum; i++)
    {
        if(!visited[i])
        {    
            visited[i] = true;
            printf("%st", G.vexs[i]);
            rear = (rear + 1) % MAX_VEX;
            Queue[rear] = i; //将此顶点下标入队
            while(rear != front)//当队列不为空
            {    
                front = (front + 1) % MAX_VEX;
                i = Queue[front];//队首元素出队赋值给i,便于寻找一下个邻接点
                for(j = 0; j < G.vexNum; j++)
                {
                    if(!visited[j] && G.arc[i][j] != INF)//找到未被访问的顶点并且属于当前顶点i的邻接点
                    {
                        visited[j] = true;
                        printf("%st", G.vexs[j]);
                        rear = (rear + 1) % MAX_VEX;
                        Queue[rear] = j;//将找到顶点循环依次序入队
                    }
                }
            }
        }
    }
    printf("nn");
}
//最小生成树-Prim算法
void Prim(MGraph G, int start)
{    
    int i;
    for(i = 0; i < G.vexNum; i++)
    {    
        minEdge[i].adjvex = start;
        minEdge[i].lowcost = G.arc[start][i];
    }
    minEdge[start].lowcost = 0;//lowcost数组值为0表示该下标对应顶点已经并入集合
    for(i = 0; i < G.vexNum - 1; i++)//n个顶点最小生成树共n-1条边
    {    
        int j = 0;
        int k = 0;
        int min = INF;
        //循环找寻最小权值
        while(j < G.vexNum)
        {
            if(minEdge[j].lowcost != 0 && minEdge[j].lowcost < min)
            {
                min = minEdge[j].lowcost;
                k = j;
            }
            j++;
        }
        printf("(%d, %d)%d-->", minEdge[k].adjvex, k, minEdge[k].lowcost);
        minEdge[k].lowcost  = 0;//将lowcost数组值置0表示该下标对应顶点已经并入集合
        //更新lowcost数组值,若新点位k的邻接点有最小权值边则替换
        for(j = 0; j < G.vexNum; j++)
        {
            if(minEdge[j].lowcost != 0 && G.arc[k][j] < minEdge[j].lowcost)
            {
                minEdge[j].lowcost = G.arc[k][j];
                minEdge[j].adjvex = k;
            }
        }
    }
}
 

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/510911.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号