数据结构——图的深度优先搜索使用邻接表

/* 图的邻接表表示法,以及DFS遍历 */

//思考:如果不是连通图,此代码还适用吗
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>//bool

#define MAX 99  //最大顶点数
bool visited[4] = {false};

typedef int Vertex;     //用顶点下标表示顶点
typedef int WeightType;//边的权值为int
typedef char DataType;//顶点存储的数据类型设为字符型

//边的定义
typedef struct Enode *Ptr_To_Enode;
struct Enode
{
    Vertex v1,v2;   //有向边<v1,v2>
    WeightType w;   //权重
};
typedef Ptr_To_Enode Edge;

//邻接点的定义
typedef struct AdjVnode *Ptr_To_AdjVnode;
struct AdjVnode
{
    Vertex adjv;    //邻接点的下标
    WeightType w;   //边权重
    struct AdjVnode* next;//指向下一个邻接点的指针
};

//顶点表头结点的定义
typedef struct Vnode
{
    Ptr_To_AdjVnode firstedge;  //边表头指针
    DataType data;
}AdjList[MAX];  //AdjList是邻接表类型

//图结点的定义
typedef struct Gnode *Ptr_To_Gnode;
struct Gnode
{
    int Nv; //顶点数
    int Ne;//边数
    AdjList G;//邻接表
};
typedef Ptr_To_Gnode LGraph;//以邻接表的方式存储图类型

//初始化一个有VertexNum个顶点但没有边的图 
LGraph Create_Graph(int vertexnum)
{
    Vertex v;
    LGraph graph;
    graph = malloc(sizeof(struct Gnode));
    graph->Nv = vertexnum;
    graph->Ne = 0;
    /* 初始化邻接表头指针 */
    for ( v = 0; v < graph->Nv; v++)
        graph->G[v].firstedge = NULL;
    
    return graph;
}

//插入边
void insert_edge(LGraph G,Edge E)
{
    Ptr_To_AdjVnode newnode;
//将边E<v1,v2>插入图中
    newnode = malloc(sizeof(struct AdjVnode));//为v2建立新的邻接点
    newnode->adjv = E->v2;
    newnode->w = E->w;
    newnode->next = G->G[E->v1].firstedge;//头插法
    G->G[E->v1].firstedge = newnode;
//如果是无向图的话,还需插入<v2,v1>
/*    newnode = malloc(sizeof(struct AdjVnode));//为v1建立新的邻接点
    newnode->adjv = E->v1;
    newnode->w = E->w;
    newnode->next = G->G[E->v2].firstedge;
    G->G[E->v2].firstedge = newnode;
由于main函数中的edge数组已经包含了<v2,v1>*/
}

LGraph build_graph(int edge[][3],char data[])
{
    LGraph Graph;   //图
    Edge E; //边
    Vertex V;//顶点下标
    int nv = 4,ne = 10;//顶点数量,边的数量

    Graph = Create_Graph(nv);//初始化有nv个顶点无边的图
    Graph->Ne = ne;
    if (Graph->Ne != 0)
    {
        E = malloc(sizeof(struct Enode));
        for (int i = 0; i < Graph->Ne; i++)
        {
            E->v1 = edge[i][0];
            E->v2 = edge[i][1];
            E->w = edge[i][2];
            insert_edge(Graph,E);//将边插入图中
        }
        
    }
    for(int h = 0;h < Graph->Nv;h++)
        Graph->G[h].data = data[h];

    return Graph;
}

//DFS
void Visit(Vertex V)
{
    printf("正在访问顶点%d\n",V);

}

void DFS(LGraph Graph,Vertex V,void (*Visit)(Vertex))
{
    /* 以V为出发点对邻接表存储的图Graph进行DFS搜索 */
    Ptr_To_AdjVnode W;

    Visit(V);
    visited[V] = true;
    // printf("data:%s\t",Graph->G[V].data);
    for ( W = Graph->G[V].firstedge; W ; W = W->next)//递归遍历无向图
    {
        
        if(!visited[W->adjv])        
            DFS(Graph,W->adjv,Visit);
    }
    printf("data:%c\tV:%d\tj:%d\tw:%d\t\n",Graph->G[V].data,V,Graph->G[V].firstedge->adjv,Graph->G[V].firstedge->w);
}//使用%s的话会调用字符串,那样会越界

int main(void)
{
    //分别为v1,v2,w
    int edge[][3] = {{0,1,13},{0,2,11},{0,3,17},{1,0,13},{1,2,10},
                    {2,0,11},{2,1,10},{2,3,7},{3,2,7},{3,0,17}};
    char data[4] = {'a','b','c','d'};
    LGraph G;
    G = build_graph(edge,data);
    DFS(G,0,Visit);

    return 0;
}



 




基本上就是浙江大学的数据结构课程的代码

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值