C语言数据结构——图的邻接表

本文介绍了如何使用C语言实现图的邻接表数据结构,以头插法构建无向图的邻接表,并展示了邻接矩阵的表示。文章包括邻接表的生成、打印以及在有向图中的应用,还提到了在处理输入和输出时对索引进行调整以符合人们习惯的处理方式。
摘要由CSDN通过智能技术生成

 

  转载地址:https://blog.csdn.net/qq_39630587/article/details/77409869

邻接表结构
邻接表数据结构类型如下:

#define MaxVertices 100 
typedef struct node     //建立边表
{
    int adjvex;         //该边所指向的节点位置
    node* next;         //指向下一条边
//    int info;         //可用存储该边的权值
} ArcNode;
typedef struct          //建立顶点表
{
    int data;
    ArcNode *first;
} VerNode;
typedef struct          //建立邻接表
{
    VerNode adjList[MaxVertices];     //邻接表的顶点
    int n,e;                          //总顶点数和边数
} AdjList;

注:边表为链表结构,插入元素有头插法和尾插法两种,这里以头插法为例。

对应的,我们得到如下的结构:
邻接表数据结构
我们以无向图为例:
无向图
写出相应的邻接矩阵:
邻接表实际


 运行结果:(输入从0开始)

邻接表生成函数:

void CreateGraph(AdjList *L)          //生成邻接表
{
    int i,a,b;
    ArcNode *s;                       //声明一个边表类型的指针
    printf("请输入总顶点和总边数:\n");
    scanf("%d %d",&L->n,&L->e);
    printf("建立顶点表:\n");
    for(i=0; i<L->n; i++)
    {
        scanf("%d",&L->adjList[i].data);    //给顶点的数据域赋初值
        L->adjList[i].first = NULL;         //初始顶点表的指针域置空
    }
    //采用头插法创建
    printf("建立边表:\n");
    for(i=0; i<L->e; i++)
    {
        //输入顶点从0开始
        printf("请输入有连接的顶点:\n");
        scanf("%d %d",&a,&b);
//输入顶点大于0
//        a-=1;
//        b-=1;
        //无向图和邻接矩阵的无向图一样,是对称的
        s = (ArcNode*)malloc(sizeof(ArcNode));  //为新建边表申请堆空间
        s->adjvex = b;                          //边表的数据域赋初值,指示边表的节点位置
        s->next = L->adjList[a].first;          //头插法
        L->adjList[a].first = s;

        s = (ArcNode*)malloc(sizeof(ArcNode));
        s->adjvex = a;
        s->next = L->adjList[b].first;
        L->adjList[b].first = s;
    }
}

邻接表打印函数:

void DisGraph(AdjList *L)
{
    for(i=0;i<L->n;i++)
    {
//      printf("%d->",i+1);
        printf("%d->",i);  //输入从0开始
        while(1)
        {
            if(L->adjList[i].first == NULL)
            {
                printf("^");
                break;
            }
//            printf("%d->",L->adjList[i].first->adjvex+1);
            printf("%d->",L->adjList[i].first->adjvex);  //输入从0开始
            L->adjList[i].first = L->adjList[i].first->next;
        }
        printf("\n");
    }

}

注:①②处是由于边表的顺序是对应的是顶点表数组的顺序,所以起始数组为G->adjlist[0],但是按照人们的输入习惯,我们从1开始,所以对于每个输入的i,j进行减1处理存储,再对于输出的G->adjlist[i].edgenext->adjvex进行加1处理,保证输入输出的统一性


具体代码实现:

#include <stdio.h>
#include <stdlib.h>
#define MaxVertices 100
typedef struct node     //建立边表
{
    int adjvex;         //该边所指向的节点位置
    node* next;         //指向下一条边
//    int info;         //可用存储该边的权值
} ArcNode;
typedef struct          //建立顶点表
{
    int data;
    ArcNode *first;
} VerNode;
typedef struct          //建立邻接表
{
    VerNode adjList[MaxVertices];     //邻接表的顶点
    int n,e;                          //总顶点数和边数
} AdjList;
void CreateGraph(AdjList *L)          //生成邻接表
{
    int i,a,b;
    ArcNode *s;                       //声明一个边表类型的指针
    printf("请输入总顶点和总边数:\n");
    scanf("%d %d",&L->n,&L->e);
    printf("建立顶点表:\n");
    for(i=0; i<L->n; i++)
    {
        scanf("%d",&L->adjList[i].data);    //给顶点的数据域赋初值
        L->adjList[i].first = NULL;         //初始顶点表的指针域置空
    }
    //采用头插法创建
    printf("建立边表:\n");
    for(i=0; i<L->e; i++)
    {
        //输入顶点从0开始
        printf("请输入有连接的顶点:\n");
        scanf("%d %d",&a,&b);
//输入顶点大于0
//        a-=1;
//        b-=1;
        //无向图和邻接矩阵的无向图一样,是对称的
        s = (ArcNode*)malloc(sizeof(ArcNode));  //为新建边表申请堆空间
        s->adjvex = b;                          //边表的数据域赋初值,指示边表的节点位置
        s->next = L->adjList[a].first;          //头插法
        L->adjList[a].first = s;

        s = (ArcNode*)malloc(sizeof(ArcNode));
        s->adjvex = a;
        s->next = L->adjList[b].first;
        L->adjList[b].first = s;
    }
}
void DisGraph(AdjList *L)
{
    int i;
    for(i=0;i<L->n;i++)
    {
//      printf("%d->",i+1);
        printf("%d->",i);  //输入从0开始
        while(1)
        {
            if(L->adjList[i].first == NULL)
            {
                printf("^");
                break;
            }
//            printf("%d->",L->adjList[i].first->adjvex+1);
            printf("%d->",L->adjList[i].first->adjvex);  //输入从0开始
            L->adjList[i].first = L->adjList[i].first->next;
        }
        printf("\n");
    }

}
int main()
{
    AdjList *L = (AdjList*)malloc(sizeof(AdjList));     //为邻接表申请堆空间
    CreateGraph(L);
    DisGraph(L);
}

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

邻接表有向图

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

运行结果:

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

加入权值后:

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

邻接表生成函数:

void CreateGraph(AdjList *L)
{
    int i,a,b;
    ArcNode *s;
    printf("请输入总顶点数和边数:\n");
    scanf("%d %d",&L->n,&L->e);
    printf("建立顶点表:\n");
    for(i=0;i<L->n;i++)
    {
        scanf("%d",&L->adjList[i].data);
        L->adjList[i].first = NULL;
    }
    printf("建立边表:\n");
    for(i=0;i<L->e;i++)
    {
        printf("请输入有连接的顶点:\n");
        scanf("%d %d",&a,&b);
        //输入从1开始
        a-=1;
        b-=1;

        s = (ArcNode*)malloc(sizeof(ArcNode));
        s->adjvex = b;
        s->next = L->adjList[a].first;
        L->adjList[a].first = s;
    }
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

全部代码:

#include <stdio.h>
#include <stdlib.h>
#define MaxVertices 100
typedef struct node         //边表
{
    int adjvex;
    node* next;
    //int info;             //存储权值
}ArcNode;
typedef struct              //顶点表
{
    int data;
    ArcNode* first;
}VerNode;
typedef struct              //邻接表
{
    VerNode adjList[MaxVertices];
    int n,e;
}AdjList;
void CreateGraph(AdjList *L)
{
    int i,a,b;
    ArcNode *s;
    printf("请输入总顶点数和边数:\n");
    scanf("%d %d",&L->n,&L->e);
    printf("建立顶点表:\n");
    for(i=0;i<L->n;i++)
    {
        scanf("%d",&L->adjList[i].data);
        L->adjList[i].first = NULL;
    }
    printf("建立边表:\n");
    for(i=0;i<L->e;i++)
    {
        printf("请输入有连接的顶点:\n");
        scanf("%d %d",&a,&b);
        //输入从1开始
        a-=1;
        b-=1;

        s = (ArcNode*)malloc(sizeof(ArcNode));
        s->adjvex = b;
        s->next = L->adjList[a].first;
        L->adjList[a].first = s;
    }
}
void DisGraph(AdjList *L)
{
    int i;
    for(i=0;i<L->n;i++)
    {
        printf("%d->",i+1);
        while(1)
        {
            if(L->adjList[i].first == NULL)
            {
                printf("^");
                break;
            }
            printf("%d->",L->adjList[i].first->adjvex+1);
            L->adjList[i].first = L->adjList[i].first->next;
        }
        printf("\n");
    }
}
int main()
{
    AdjList *L = (AdjList*)malloc(sizeof(AdjList));
    CreateGraph(L);
    DisGraph(L);
}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==

 

  • 12
    点赞
  • 85
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值