图-邻接表的建立

本文介绍了一种使用C语言实现邻接表的方法,包括创建表头、存储顶点及边信息,并通过示例代码详细展示了如何构建邻接表以及如何遍历打印各个顶点及其对应的边。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

建立邻接表(分析)

存储各个点的信息:

#include<stdio.h>
#include<stdlib.h>
#include<string.h> 
#define max 110
typedef struct graphhead{//表头(表的第一列)用来存各个顶点信息 
	int data;
	struct node* next;
}List[max];//有多个顶点,所以用数组 

存储各个点后继点信息:

struct node{//结构体节点,用来表示顶点的后继点的信息 
	int xuhao;//存后继点的序号(序号是用来找该后继点信息) 
	struct node* xuhaonext;//后继指针 
};

邻接表的结构体:

struct graph{
	int pnum,snum;//分别表示表中点的数量与边的数量 
	List list;//将表示各点信息的数组作成员可访问各个点的信息 
};

查找点的序号:

int findxuhao(graph* g,int id)//查找序号,id为一个点的名字(信息),查找该点在list中所处的编号 
{
	for(int i=1;i<=g->pnum;i++)
	{
		if(id==g->list[i].data)return i;
	}
	return -1;
}

建立邻接表:

void create(graph* g)//创建邻接表 
{
	int start,end,n,m;
	printf("输入节点数,边数:\n");
	scanf("%d%d",&g->pnum,&g->snum);
	for(int i=1;i<=g->pnum;i++)
	{
		printf("请输入第%d个顶点的信息:\n",i);
		scanf("%d",&g->list[i].data);
		g->list[i].next=NULL;
	}
	printf("请输入每条边的指向:\n");
	for(int i=1;i<=g->snum;i++)
	{
		printf("第%d条边:\n",i);
		scanf("%d%d",&start,&end);
		m=findxuhao(g,start);
		n=findxuhao(g,end);//查找指向点与被指向点的序号 
		if(m==-1||n==-1)printf("建立失败!\n");
		node* p=(node*)malloc(sizeof(node));
		
		p->xuhao=n;//头插法插入新建的指针 
		p->xuhaonext=g->list[m].next;
		g->list[m].next=p;
	}
}

打印出该点指向的链:

void PrintLink(graph* g ,node* xuhaonext) {//打印出该点指向的所有点 
	while (xuhaonext!= NULL) {
		printf("%4d",g->list[xuhaonext->xuhao].data);
		xuhaonext = xuhaonext->xuhaonext;
	}
	printf("\n");
}

打印出各个点:

void disp(graph* g) {//按序号顺序打印出各个点的信息 
	printf("邻接表:\n");
	for (int i = 1; i <= g->pnum; i++) {
		printf("%4d",g->list[i].data);
		PrintLink(g,g->list[i].next);
	}
}

主函数:

int main()
{
	graph* g=(graph*)malloc(sizeof(graph));
	create(g);
	disp(g);
	return 0;
}

自己建一个表模拟一下思路会更清楚~

### 构建邻接表 #### 练习题目描述 给定一个无向,通过输入顶点数、边数以及各条边所连接的两个顶点的信息,使用C++编程实现该无向对应的邻接表示形式并将其输出。 对于每一个测试案例,在一行内先给出整数N代节点总数(即顶点数量),随后是一个M明有多少条边存在。紧接着会有M行数据,每一行都由一对u v组成用来指明一条从编号为u到v之间的连线[^2]。 #### C++代码示例 下面是一份基于上述要求编写的程序: ```cpp #include <iostream> #include <vector> using namespace std; // 定义链中的节点结构体 struct Edge { int dest; Edge* next; }; void addEdge(vector<Edge*>& adjList, int u, int v) { // 向adjList[u]添加指向v的新边缘 Edge* new_edge = new Edge{v, adjList[u]}; adjList[u] = new_edge; // 对于无向还需要反向添加 new_edge = new Edge{u, adjList[v]}; adjList[v] = new_edge; } int main() { int N, M; cin >> N >> M; // 输入顶点数目和边的数量 vector<Edge*> adjList(N, nullptr); // 初始化大小为N的邻接,默认为空(nullptr) while (M--) { // 循环读取所有的边 int u, v; cin >> u >> v; addEdge(adjList, u, v); } // 输出邻接表的内容 for(int i = 0; i < N; ++i){ cout << "Vertex " << i << ": "; for(Edge* e = adjList[i]; e != nullptr; e=e->next){ cout << "->" << e->dest; } cout << endl; } return 0; } ``` 此段代码实现了基本功能:接收用户输入有关形的具体参数之后建立相应的邻接表,并最终把结果展示出来。注意这里的`addEdge()`函数负责处理双向链接的情况,因为它既会更新起点也会更新终点处的邻居关系。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值