无向图的建立及深度优先遍历

无向图的建立及深度优先遍历

一个图,有很多存储结构,例如邻接矩阵,邻接表,十字链表,邻接多重表等
下面写写一个无向图的邻接表存储,并实现其深度优先(DFS)遍历:

  • 详细了解请参照严蔚敏写的《数据结构c语言版》163页(主要了解头结点和边结点)

话不多说直接上代码吧

代码块

// 实验四无向图的深度优先搜索.cpp: 定义控制台应用程序的入口点。
//

#include "stdafx.h"

typedef struct ArcNode {   //表(边)节点,存储边信息的结构体 
    int adjvex;       //存储与该边相连的另一个节点的索引 
    struct ArcNode *nextarc; //存储与表头节点相连的其他边节点的指针 
    string info;             //存储边的信息,例如权值 
}ArcNode;

typedef struct VNode {//存储头节点信息的结构体 
    char date;              //存储头节点包含的数据,例如头节点的名字 
    ArcNode * firstarc;      //指向链表的指针 
}VNode, AdjList[MAX_VERTEX_NUM];

typedef struct {
    AdjList vertices;          //存储头节点的数组 
    int vexnum, arcnum;        //当前图的vexnum顶点数和arcnum弧数 
    int kind;//图的种类, 
}ALGraph;

int LocateVex(ALGraph &G, char &v1)   //查找节点V1在图G的存储节点数组中的索引位置 
{
    int i;
    for (i = 0;i<G.vexnum;i++)
    {
        if (G.vertices[i].date == v1) //如果数组中有这个节点,返回该节点在数组中的索引 
            return i;
    }
    printf("未查找到%c节点!", v1);
    return ERROR;
}

//以邻接表存储创建图 
void CreateAL(ALGraph &G)
{
    ArcNode *p, *q;
    char v1, v2;
    char v;
    int i, j, k, n;
    cout << "请输入图的顶点数和弧数:" << endl;
    cin >> G.vexnum; //输入图的顶点数量 
    cin >> G.arcnum; //输入图的弧(边)的数量 
    cout << "请输入顶点:" << endl;

    for (i = 0;i<G.vexnum;i++) //创建头结点 
    {
        cin >> v;   //输入顶点数据 
        G.vertices[i].date = v;//存入顶点数据
        G.vertices[i].firstarc = NULL;//将指针域置空
    }

    for (k = 0;k<G.arcnum;k++) //创建边,并连接头结点 
    {
        cout << "请输入弧尾和弧头:";
        cin >> v1;  //v1为弧尾 
        cin >> v2;   //v2为弧头 
        i = LocateVex(G, v1);j = LocateVex(G, v2);//得到弧尾弧头在数组中的下标
        if (i==ERROR||j==ERROR) {//当i,j返回错误时退出
            exit(ERROR);
        }

        if (G.vertices[i].firstarc == NULL)  //如果头节点指针域为空新建一个边节点,让头节点的指针指向该边节点 
        {
            p = (ArcNode *)new ArcNode;
            G.vertices[i].firstarc = p;
            q = G.vertices[i].firstarc;
        }
        else        //链表的插入 
        {
            q = G.vertices[i].firstarc;//获取头结点的表头指针 
            for (n = 0;n<G.arcnum;n++, q = q->nextarc)//将q指针移动至链表的尾巴处 
            {
                if (!q->nextarc)
                    break;
            }
            p = (ArcNode *)new ArcNode;
            q->nextarc = p; //将该边(弧)加入到链表中 
            q = q->nextarc;
        }
        q->adjvex = j;  //记录弧头的索引 
        q->nextarc = NULL;
    }
    cout << "图构建成功!" << endl;
}
void DFS(ALGraph &G,int* visited,int v) {//从第v个节点出发递归深度优先遍历图G
    visited[v] = 1;
    cout << G.vertices[v].date << " ";
    ArcNode* m;
    if (G.vertices[v].firstarc == NULL)//当第v个节点没有邻接点时返回
        return;
    //对第V个节点的所有邻接点进行DFS遍历
    for (m = G.vertices[v].firstarc;m != NULL;m = m->nextarc) {
        if (!visited[m->adjvex])
            DFS(G, visited, m->adjvex);
    }
}
//基于邻接表的深度优先算法
void DFStraverse(ALGraph &G, int v) {//从第v个顶点出发递归深度遍历图G
    int* visited = (int*)calloc(G.vexnum , sizeof(int));//开一个大小为节点数,数据为0的辅助数组
    if (visited == NULL)
        exit(ERROR);
    int n=0;//记录连通分量的个数
    for (;v < G.vexnum;++v) {
        if (!visited[v]) {
            printf("第%d连通分量:", ++n);
            DFS(G, visited, v);//对尚未访问的头节点调用DFS
            cout << endl;
        }
    }
    cout << endl;
}
int main()
{
    ALGraph G;
    CreateAL(G);
    DFStraverse(G, 0);

    return 0;
}

实验运行结果截图:

《无向图的建立及深度优先遍历》

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