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

本文介绍了如何使用邻接表来存储无向图,并实现了图的深度优先遍历(DFS)。详细讲解了邻接表结构,并提供了相关代码实现和实验运行结果。

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

一个图,有很多存储结构,例如邻接矩阵,邻接表,十字链表,邻接多重表等
下面写写一个无向图的邻接表存储,并实现其深度优先(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;
}

实验运行结果截图:

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值