C语言 图操作--邻接表法

C语言 图操作–邻接表法

这里只是图的创建部分,图的遍历会在后面更新。
一、图的介绍
图是一种相较于链表和树更为复杂的数据结构。在线性表中,数据元素之间仅有线性关系,每个元素只有一个直接前驱和一个直接后继(每个元素之间一个一个逐个相连)。在树形结构中,数据元素之间有着明显的层次关系,上一层元素能和下层多个元素相关,但是下层元素只能与一个上层元素相关。而在图结构中,节点之间的关系任意,任何两个顶点都可能相连。
图结构如图所示在这里插入图片描述

此中为“离散数学”中的图理论。
二、图的术语
接下来介绍图结构中的一些术语。
1.顶点 图中的数据元素通常称为顶点。
2.边 两顶点间的连线称为边。
3.V是顶点的有穷非空集合。
4.VR是两个顶点之间关系的集合,也是边的集合。
5.通常表示为:G(V,E),G表示一个图,V是图G中顶点的集合,E是图G中边的集合。
6.无向边:若顶点A到顶点B的边没有方向,称这条边为无向边,用无序偶对(A,B)或(B,A)表示。

7.有向边:若顶点A到顶点B的边有方向,称这条边为有向边,也称为弧(Arc),用有序对 < B, A >表示;B表示弧尾,A表示弧头
8.由无向边构成的图为无向图
9.由有向边构成的图为有向图
这里只是一些最基本的术语,大家可以自己去看看大佬们的介绍。
三、图结构的构建
1.用邻接表创建图结构既是使用链表记录一个顶点的所有邻近顶点,再用数组存取顶点信息,当然顶点信息也可以用链表串起来。
2.邻接表的结构体定义代码如图所示

void clear() //该函数起到一个清空缓冲区的作用,防止多部输入错误。
{
    int ch;
    while ((ch = getchar()) != EOF && ch != '\n')
        ;
}
struct Node  //定义邻接表的节点属性
{
    int data;//邻接表的数据域
    struct Node *next; //邻接表的指针域
};
struct Head   //定义图的顶点的属性
{
    char info;  //存储图顶点信息
    struct Node *dajoin;  //定义临近顶点指针
};
struct Map  //定义图结构
{
    int side;  //记录边的数量
    int spot;  //记录图的数量
    struct Head head[20];  //用数组记录顶点下标
};

3.创建一个图
定义完结构体之后需要创建图结构,并对输入的数据进行存储。将存数据的各个顶点进行关联。

void creat_graph(struct Map *map)
{
    int i, j;
    char S1 = 0;
    char S2 = 0;
    struct Node *p;
    printf("请输入要建立的顶点数:\n");
    scanf("%d", &map->spot);//将输入的顶点数存入图结构体变量中
    clear();//清空缓冲区  下同
    printf("请输入要建立的边的数:\n");
    scanf("%d", &map->side);//将输入的边数存入图结构体变量中
    clear();

    for (i = 0; i < map->spot; i++)
    {
        map->head[i].info = i + 'A';//创建n个顶点并分别赋值为A到i+"A"
        map->head[i].dajoin = NULL;//初始化顶点,使顶点邻接点为空。
    }
    printf("请输入要建立的边:\n");
    for (j = 0; j < map->side; j++)
    {
       scanf("%c%c", &S1, &S2);  //通过输入字母 如AB BC 建立边并连接顶点
		getchar();
		if (S1 != ' ' && S2 != ' ' && S1 != S2)//如果s1 s2都不为‘ ’ 且不等。
		{
			insert(map, S1, S2);//把s2顶点挂在s1顶点下。此函数定义后面介绍
			
		}
    }
}

4.邻接表的插入操作。
此步骤与普通的链表插入无不同,如果有不了解的可以区看我前面的博客(记得点赞加关注哦!)。此处不作过多介绍。

void insert(struct Map *map, char S1, char S2)
{
    if (map->head[B1].dajoin != NULL)  //如果该顶点下未已挂载链表则进行比较并插入
    {
        if (map->head[B1].dajoin->data > B2)
        {
            struct Node *temp = malloc(sizeof(struct Node));
            temp->data = B2;
            temp->next = map->head[B1].dajoin;
            map->head[B1].dajoin = temp;
        }
        else
        {
            struct Node *demp = map->head[B1].dajoin;
            struct Node *before = demp;
            while (demp && B2 > demp->data)
            {
                before = demp;
                demp = demp->next;
            }
            struct Node *emp = malloc(sizeof(struct Node));
            emp->data = B2;
            emp->next = before->next;
            before->next = emp;
        }
    }
    else  //如果未挂载链表则直接挂载链表
    {
        map->head[B1].dajoin = malloc(sizeof(struct Node));
        map->head[B1].dajoin->data = B2;
        map->head[B1].dajoin->next = NULL;
    }
}

5、展现图的结构关系

void print(struct Map *map)
{
    int i;
    for (i = 0; i < map->spot; i++)  //通过循环找到各个顶点之间的连接关系
    {
        char ele = i + 'A';
        struct Node *p = map->head[i].dajoin;
        printf("与%c连接的结点有:", ele);
        while (p)
        {
            char ele = p->data + 'A';
            printf("%c ", ele);
            p = p->next;
        }
        printf("\n");
    }
}

四、完整代码

#include "stdlib.h"
#include "stdio.h"
#define B1 (S1 - 'A')
#define B2 (S2 - 'A')
void clear()
{
    int ch;
    while ((ch = getchar()) != EOF && ch != '\n')
        ;
}
struct Node
{
    int data;
    struct Node *next;
};
struct Head
{
    char info;
    struct Node *dajoin;
};
struct Map
{
    int side;
    int spot;
    struct Head head[20];
};
void creat_graph(struct Map *map)
{
    int i, j;
    char S1 = 0;
    char S2 = 0;
    struct Node *p;
    printf("请输入要建立的顶点数:\n");
    scanf("%d", &map->spot);
    clear();
    printf("请输入要建立的边的数:\n");
    scanf("%d", &map->side);
    clear();

    for (i = 0; i < map->spot; i++)
    {
        map->head[i].info = i + 'A';
        map->head[i].dajoin = NULL;
    }
    printf("请输入要建立的边:\n");
    for (j = 0; j < map->side; j++)
    {
       scanf("%c%c", &S1, &S2);
		getchar();
		if (S1 != ' ' && S2 != ' ' && S1 != S2)
		{
			insert(map, S1, S2);
			
		}
    }
}
void insert(struct Map *map, char S1, char S2)
{
    if (map->head[B1].dajoin != NULL)
    {
        if (map->head[B1].dajoin->data > B2)
        {
            struct Node *temp = malloc(sizeof(struct Node));
            temp->data = B2;
            temp->next = map->head[B1].dajoin;
            map->head[B1].dajoin = temp;
        }
        else
        {
            struct Node *demp = map->head[B1].dajoin;
            struct Node *before = demp;
            while (demp && B2 > demp->data)
            {
                before = demp;
                demp = demp->next;
            }
            struct Node *emp = malloc(sizeof(struct Node));
            emp->data = B2;
            emp->next = before->next;
            before->next = emp;
        }
    }
    else
    {
        map->head[B1].dajoin = malloc(sizeof(struct Node));
        map->head[B1].dajoin->data = B2;
        map->head[B1].dajoin->next = NULL;
    }
}
void print(struct Map *map)
{
    int i;
    for (i = 0; i < map->spot; i++)
    {
        char ele = i + 'A';
        struct Node *p = map->head[i].dajoin;
        printf("与%c连接的结点有:", ele);
        while (p)
        {
            char ele = p->data + 'A';
            printf("%c ", ele);
            p = p->next;
        }
        printf("\n");
    }
}

int main()
{
    struct Map map;
   creat_graph(&map);
    print(&map);
    return 0;
}

  • 10
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
邻接表是一种的存储结构,可以用来表示稀疏。下面是一个用C语言实现邻接表存储的示例代码: ```c #include <stdio.h> #include <stdlib.h> struct AdjListNode { int dest; struct AdjListNode* next; }; struct AdjList { struct AdjListNode* head; }; struct Graph { int V; struct AdjList* array; }; struct AdjListNode* newAdjListNode(int dest) { struct AdjListNode* newNode = (struct AdjListNode*)malloc(sizeof(struct AdjListNode)); newNode->dest = dest; newNode->next = NULL; return newNode; } struct Graph* createGraph(int V) { struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph)); graph->V = V; graph->array = (struct AdjList*)malloc(V * sizeof(struct AdjList)); int i; for (i = 0; i < V; ++i) { graph->array[i].head = NULL; } return graph; } void addEdge(struct Graph* graph, int src, int dest) { struct AdjListNode* newNode = newAdjListNode(dest); newNode->next = graph->array[src].head; graph->array[src].head = newNode; newNode = newAdjListNode(src); newNode->next = graph->array[dest].head; graph->array[dest].head = newNode; } void printGraph(struct Graph* graph) { int v; for (v = 0; v < graph->V; ++v) { struct AdjListNode* pCrawl = graph->array[v].head; printf("\n Adjacency list of vertex %d\n head ", v); while (pCrawl) { printf("-> %d", pCrawl->dest); pCrawl = pCrawl->next; } printf("\n"); } } int main() { int V = 5; struct Graph* graph = createGraph(V); addEdge(graph, 0, 1); addEdge(graph, 0, 4); addEdge(graph, 1, 2); addEdge(graph, 1, 3); addEdge(graph, 1, 4); addEdge(graph, 2, 3); addEdge(graph, 3, 4); printGraph(graph); return 0; } ``` 这个示例代码创建了一个包含5个顶点的无向,然后使用邻接表存储这个,并最终输出它的邻接表。在这个示例代码中,我们首先定义了三种结构体:`AdjListNode`、`AdjList`和`Graph`。其中,`AdjListNode`表示邻接表中的一个节点,包括目标节点的编号和指向下一个节点的指针;`AdjList`表示一个节点的邻接表,包括指向第一个节点的指针;`Graph`表示整个,包括顶点数和一个指向邻接表数组的指针。 接下来,我们定义了一些函数来操作这些结构体,包括`newAdjListNode`用于创建一个新的邻接表节点,`createGraph`用于创建一个新的,`addEdge`用于向中添加一条边,`printGraph`用于输出邻接表。 在`main`函数中,我们首先创建了一个包含5个顶点的,然后添加了7条边,最后输出了这个邻接表。 以上就是一个简单的使用C语言实现邻接表存储的示例代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值