图的邻接表存储与深度优先遍历代码实现

Graph.h
Vnode结构成员firstarc在定义时赋初值NULL,在Visual Stdio 2013下编译通过,VC6.0就不行(非静态数据成员不能初始化)

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


#define MAX_VERTEX_NUM 20

typedef int InfoType, VertexType;       //在这里可以设置顶点和弧数据类型
typedef struct ArcNode
{
    int adjvex;                         //弧指向顶点的位置
    struct ArcNode *nextarc;            //指向下一条弧的指针
    InfoType *info;                     //弧相关信息的指针  例如弧长、权重等,这里用不到
}ArcNode;
typedef struct VNode
{
    VertexType data;                    //顶点信息
    ArcNode    *firstarc = NULL;        //指向第一条与该顶点相连的弧
}VNode, AdjList[MAX_VERTEX_NUM];
typedef struct
{
    AdjList vertices;                   //每个图类型中包含一个顶点数组
    int vexnum, arcnum;                 //图的顶点数和弧数
    int kind;                           //图的种类标志
}ALGraph;

void createG(ALGraph *G);
void showG(ALGraph *G);

void DFSTraverse(ALGraph G);
void DFS(ALGraph G,  int i, void(*visit) (VNode v));
inline void Print(VNode v) { printf("%d\n", v.data); }    //访问函数

Graph.cpp

#include "Graph.h"

int vnum[MAX_VERTEX_NUM] = { false };               //vnum为访问标识数组

void createG(ALGraph *G)                        //以邻接表存储方式创建图
{
    //char TemData[64];                         //暂时存储顶点数据
    int i, j;                                   //函数局部变量i,j用来记录弧的顶点
    ArcNode *s;                                 //新建的弧

    printf("请输入顶点数和边数:\n");
    scanf("%d%d", &G->vexnum, &G->arcnum);

    for (int i = 0; i < G->vexnum; i++)         //输入顶点信息,这里可以用下标唯一标识每个顶点
    {
        /*scanf("%s", TemData);
        G->vertices[i].data = (VertexType)TemData[64];*/
        G->vertices[i].data = (VertexType)i;
    }

    for (int k = 0; k < G->arcnum; k++)
    {
        scanf("%d%d", &i, &j);

        s = (ArcNode *)malloc(sizeof(ArcNode));  //将s插入到i顶点的表头
        s->adjvex = j;
        s->nextarc = G->vertices[i].firstarc;
        G->vertices[i].firstarc = s;

        s = (ArcNode *)malloc(sizeof(ArcNode));  //将s插入到j顶点的表头
        s->adjvex = i;
        s->nextarc = G->vertices[j].firstarc;
        G->vertices[j].firstarc = s;
    }
}

void showG(ALGraph *G)                          //输出表的信息
{
    ArcNode* Tem;
    for (int i = 0; i < G->vexnum; i++)
    {
        printf("%d->", i);
        Tem = G->vertices[i].firstarc;
        while (Tem != NULL)
        {
            printf("%d->", Tem->adjvex);
            Tem = Tem->nextarc;
        }
        printf("\n");
    }
}

void DFSTraverse(ALGraph G)
{                                     
    for (int i = 0; i < G.vexnum; i++)
        if (!vnum[i]) 
            DFS(G, i, Print);
}

void DFS(ALGraph G, int i, void(*visit) (VNode v))              //对表G从顶点i开始做深度优先遍历
{
    vnum[i] = true;   visit(G.vertices[i]);
    for (ArcNode *w = G.vertices[i].firstarc; w != NULL; w = w->nextarc)
    if (!vnum[w->adjvex]) 
        DFS(G, w->adjvex, Print);
}

main.cpp

#include "Graph.h"
void main()
{
    ALGraph G;

    createG(&G);
    showG(&G);
    DFSTraverse(G);
}

这里写图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
邻接表存储是一种常见的存储方式,其基本思想是将每个顶点的邻接点列表存储在一个数组中。具体来说,我们可以用一个数组来存储所有顶点,而对于每个顶点,我们用一个链表来存储其邻接点列表。 下面是一个示例邻接表存储: ![邻接表示例](https://img-blog.csdn.net/20180607170352208?watermark/2/text/aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3p4LWJsb2c=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/q/80) 对应的邻接表为: ``` 0 -> 1 -> 2 -> 3 1 -> 0 -> 2 -> 4 2 -> 0 -> 1 -> 3 -> 4 3 -> 0 -> 2 4 -> 1 -> 2 ``` 深度优先遍历(DFS)是一种常见的遍历算法,其基本思想是从某个顶点开始,沿着一条路径一直遍历到底,直到没有未访问的邻接点为止,然后回溯到上一个顶点,再选择另一条路径继续遍历,直到所有顶点都被访问过为止。 下面是深度优先遍历代码实现,其中graph为邻接表存储,visited为记录每个顶点是否被访问过的数组。 ``` void DFS(int v, vector<int> *graph, bool *visited) { visited[v] = true; cout << v << " "; for (int i = 0; i < graph[v].size(); i++) { int u = graph[v][i]; if (!visited[u]) { DFS(u, graph, visited); } } } ``` 其中v表示当前遍历到的顶点,graph表示邻接表存储,visited表示记录每个顶点是否被访问过的数组。在遍历过程中,我们首先将当前顶点标记为已访问,并输出其值。然后依次遍历其邻接点,对于每个未访问过的邻接点,递归调用DFS函数进行遍历。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值