图的遍历(DFS、BFS)使用邻接矩阵(数组)作为存储结构--C语言

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <limits.h>

#define MAX_VERTEX_NUM 20 //最大顶点个数 
#define INFINITY INT_MAX //最大值∞ 

typedef char VertexType;   //顶点向量类型 
typedef int VRType;       
typedef int InfoType;
typedef int QElemType;

//图的数组存储表示 
 typedef struct{
    VertexType vexs[MAX_VERTEX_NUM];    //顶点向量
    VRType arcs[MAX_VERTEX_NUM][MAX_VERTEX_NUM];;  //邻接矩阵,于无权图1、0表示两个顶点是否相邻,对于有权图为权值
    int vexnum,arcnum; //图的顶点数和弧数
}MGraph;

bool visited[MAX_VERTEX_NUM];  //标记顶点是否被访问,访问为true,否则为false

//查找顶点在顶点向量中的位置
int locateVertex(MGraph umg, VertexType v)
{
    int i;
    for(i=0;i<umg.vexnum;i++)
    {
        if(v == umg.vexs[i])
            return i;
    }
    return -1;
 } 
//创建无向(有向)无权图
createUMGraph(MGraph *umg)
{
    int i,j,v;
    char v1,v2;
    printf("输入无权图的顶点数和边数\n");
    scanf("%d %d",&(*umg).vexnum,&(*umg).arcnum);
    for(v=0;v<(*umg).vexnum;v++)
        visited[v] = false;
    getchar();
    printf("输入顶点名称\n");
    for(v=0;v<(*umg).vexnum;v++)
    {
        printf("输入第%d个顶点名称:",v);
        scanf("%c",&(*umg).vexs[v]);
        getchar();
    }

    //初始化邻接矩阵
    for(i=0;i<(*umg).vexnum;i++)
        for(j=0;j<(*umg).vexnum;j++)
                (*umg).arcs[i][j] = 0;

    //将图中相邻的顶点的邻接矩阵值设为1,不相邻仍为0 
    printf("输入边的信息,输入边的两个顶点名称v1 v2\n");
    for(v=0;v<(*umg).arcnum;v++)
    {
        printf("输入第%d条边两个顶点:",v);
        scanf("%c %c",&v1,&v2);
        getchar();
        printf("\n");
        i = locateVertex(*umg,v1);
        j = locateVertex(*umg,v2);
    // (*umg).arcs[i][j] = (*umg).arcs[j][i] = 1; //由于是无向图,因此一条边关联两个顶点 
        (*umg).arcs[i][j] = 1;    //有向图,边为单向 
    }    
}

//创建无向(有向)有权图
createMGraph(MGraph *mg)
{
    int i,j,v,w;
    char v1,v2;
    printf("输入有权图的顶点数和边数\n");
    scanf("%d %d",&(*mg).vexnum,&(*mg).arcnum);
    for(v=0;v<(*mg).vexnum;v++)
        visited[v] = false;
    getchar();
    printf("输入顶点名称\n");
    for(v=0;v<(*mg).vexnum;v++)
    {
        printf("输入第%d个顶点名称:",v);
        scanf("%c",&(*mg).vexs[v]);
        getchar();
    }

    //初始化邻接矩阵
    for(i=0;i<(*mg).vexnum;i++)
        for(j=0;j<(*mg).vexnum;j++)
                (*mg).arcs[i][j] = INFINITY;

    //将图中相邻的顶点的邻接矩阵值设为边的权值 
    printf("输入边的信息,输入边的两个顶点名称和权值v1 v2 w\n");
    for(v=0;v<(*mg).arcnum;v++)
    {
        printf("输入第%d条边两个顶点和权值:",v);
        scanf("%c %c %d",&v1,&v2,&w);
        getchar();
        i = locateVertex(*mg,v1);
        j = locateVertex(*mg,v2);
    // (*mg).arcs[i][j] = (*mg).arcs[j][i] = w; //由于是无向图,因此一条边关联两个顶点 
        (*mg).arcs[i][j] = w;    //有向图,边为单向 
    }    
}

//打印图的临界矩阵
void print(MGraph G)
{
    int i,j;
    printf("图的邻接矩阵\n");
    for(i=0;i<G.vexnum;i++)
    {
        for(j=0;j<G.vexnum;j++)
        {
            if(G.arcs[i][j]!=INFINITY)
                printf("%d ",G.arcs[i][j]);
            else
                printf("∞ ");
        }       
        printf("\n");
    }
    printf("\n");
 } 

//深度优先遍历图 
int FirstAdjVex(MGraph G,int v)
{   //获取与顶点v相邻的第一个顶点下标 
    int i;
    for(i=0;i<G.vexnum;i++)
    {
        if(G.arcs[v][i]!=0 && G.arcs[v][i]!=INFINITY && !visited[i])
            return i;
    }
    return -1;
}

int NextAdjVex(MGraph G,int v,int w)
{   //得到v的下一个未被访问的相邻顶点下标 
    int i;
    for(i=w;i<G.vexnum;i++)
    {
        if(G.arcs[v][i]!=0 && G.arcs[v][i]!=INFINITY && !visited[i])
            return i;
     } 
     return -1;
}

void DFS(MGraph G,int v)
{
    int w;
    visited[v] = true;
    printf("%c ",G.vexs[v]);         //访问第v个顶点 
    for(w = FirstAdjVex(G,v); w >= 0;w = NextAdjVex(G,v,w))
        if(!visited[w])
            DFS(G,w);              //对v的尚未访问的邻接顶点w递归调用DFS 
}

void DFSTraverse(MGraph G)
{
    printf("深度优先遍历序列:"); 
    int v;
    for(v = 0; v<G.vexnum;v++)
        visited[v] = false;
    for(v=0;v<G.vexnum;v++)
        if(!visited[v])
            DFS(G,v);
    printf("\n");
 } 


//广度优先遍历

//创建用于广度优先遍历的队列
typedef struct QNode
{
    QElemType data;
    struct QNode *qnext;
}QNode,*PQNode;

typedef struct Queue
{
    PQNode front;
    PQNode rear;
}Queue,*PQueue;

//初始化一个空队列 
PQueue initQueue()
{
    PQueue pqueue = (PQueue)malloc(sizeof(Queue));
    PQNode pqnode = (PQNode)malloc(sizeof(QNode));
    if(pqnode==NULL)
    {
        printf("队列头空间申请失败!\n");
        exit(-1);
    }
    pqueue->front = pqueue->rear = pqnode;
    pqnode->qnext = NULL;
    return pqueue;
}

//队尾入队
void enQueue(PQueue pqueue,QElemType data)
{
    PQNode pqnode = (PQNode)malloc(sizeof(QNode));
    if(pqnode==NULL)
    {
        printf("队列结点申请失败!\n");
        exit(-1);
    }
    pqnode->data = data;
    pqnode->qnext = NULL;
    pqueue->rear->qnext = pqnode;
    pqueue->rear = pqnode;
 } 
//判断队列是否为空
bool isEmpty(PQueue pqueue)
{
    if(pqueue->front == pqueue->rear)
        return true;
    return false;
 } 
//队头出队
QElemType deQueue(PQueue pqueue)
{
    if(isEmpty(pqueue))
    {
        printf("队列为空\n");
        exit(-1);
    }

    PQNode pqnode = pqueue->front->qnext;
    pqueue->front->qnext = pqnode->qnext;
    if(pqnode == pqueue->rear)
        pqueue->rear = pqueue->front;
    QElemType data = pqnode->data;
    free(pqnode);
    return data;

}
void BFSTraverse(MGraph G)
{   
    printf("广度优先遍历序列:");
    int i,v,w;
    for(i=0;i<G.vexnum;i++)
        visited[i] = false;
    PQueue pqueue = initQueue();    //初始化辅助队列 
    for(i=0;i<G.vexnum;i++)
    {
        if(!visited[i])             //i未被访问 
        {
            visited[i] = true;
            printf("%c ",G.vexs[i]);
            enQueue(pqueue,i);
            while(!isEmpty(pqueue))
            {
                v = deQueue(pqueue);    //队头元素出队 
                for(w=FirstAdjVex(G,v);w>=0;w=NextAdjVex(G,v,w))
                    if(!visited[w])            //w为v的尚未访问的邻接顶点 
                    {
                        visited[w] = true;
                        printf("%c ",G.vexs[w]);
                        enQueue(pqueue,w);
                    }

            }
        }
    }
    printf("\n");
 } 
 int main()
 {
 // MGraph umg; //无权图
// createUMGraph(&umg); //创建无权图 
// print(umg);
    MGraph mg;
    createMGraph(&mg);
    print(mg);
    DFSTraverse(mg);
    BFSTraverse(mg);
    return 0;
 }

《图的遍历(DFS、BFS)使用邻接矩阵(数组)作为存储结构--C语言》

    原文作者:数据结构之图
    原文地址: https://blog.csdn.net/haofight/article/details/54585218
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞