C语言数据结构——图的邻接表(尾插法&头插法),两种输入类型,VS编译。

1.输入为整数类型

#include<stdio.h>
#include<stdlib.h>
#define MaxVertices 100

//建立边表
typedef struct node		
{
	int adjvex;			//该边指向的结点位置
	struct node* next;	//指向下一条边
	int info;			//权重
}ArcNode;
//建立顶点表
typedef struct
{
	int data;
	ArcNode *first;
}VerNode;
//建立连接表
typedef struct
{
	VerNode adjList[MaxVertices];//邻接表的顶点存放数组
	int n, e;					 //顶点数,边数
}AdjList;
//生成无向邻接表
void CreateGraph1(AdjList *L)
{
	int i, a, b,c;
	ArcNode *s;										//边表
	printf_s("请输入总顶点数和总边数:\n");
	scanf_s("%d%d",&L->n,&L->e);
	printf_s("建立顶点表:\n");
	for (i = 0; i < L->n; i++)
	{
		scanf_s("%d",&L->adjList[i].data);
		L->adjList[i].first = NULL;					//初始化当前顶点指向的边表全部为空
	}
	//头插法创建边表
	printf_s("建立边表:\n");
	for (i = 0; i < L->e; i++)
	{
		printf_s("请输入有连接的顶点:");
		scanf_s("%d%d%d",&a,&b,&c);
		a -= 1; b -= 1;								//输入顶点从一开始,减去1后方便数组存储
		s = (ArcNode*)malloc(sizeof(ArcNode));	    //边表申请存储空间
		s->adjvex = b;								//边表的数据域赋值,指向边表的结点位置
		s->info = c;								//两个连接的权重

		s->next = NULL;								//尾插法
		ArcNode *p ;
		p = L->adjList[a].first;
		if (p == NULL)
		{
			L->adjList[a].first = s;
		}
		else
		{
			while (p->next)
			{
				p = p->next;
			}
			p->next = s;
		}
		/*
		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 DisGraph1(AdjList *L)
{
	int i;
	for (i = 0; i < L->n; i++)
	{
		printf_s("%d->", i+1);
		while (1)
		{
			if (L->adjList[i].first == NULL)
			{
				printf_s("^");
				break;
			}
			printf_s("%d(%d)->",L->adjList[i].first->adjvex+1,L->adjList[i].first->info);
			L->adjList[i].first = L->adjList[i].first->next;
		}
		printf_s("\n");
	}
}
void main()
{
	AdjList *L = (AdjList*)malloc(sizeof(AdjList));
	CreateGraph1(L);
	printf_s("TIP:()内的值是权值\n");
	DisGraph1(L);
}

2.输入为字符类型

#include <stdio.h>
#include<stdlib.h>
#define MaxSize 100

//建立边表
typedef struct node{
	int adjvex;				//指向边表的结点
	struct node *nextarc;	//指向下个边表结点
	int info;				//权值
}ArcNode;
//建立头表
typedef struct VNode{	
	char data;				//头结点的编号
	ArcNode *firstarc;		//指向头结点的第一个边表值,初始化为NULL
}VNode, AdjList[MaxSize];		//数组存储每一条路径
//建立邻接表
typedef struct{
	AdjList vextices;		//数组定义
	int vexnum, arcnum;		//边的总结点数和边数
}ALGraph;

//找到输入值在定义数组中的位置,并返回该位置
int LocateVex(ALGraph *G, char v)
{
	int i;
	for ( i=0; i < G->vexnum; i++)
	{
		if (G->vextices[i].data == v)
		{
			return i;
		}
	}
	return -1;
}

void CreateUDG(ALGraph *G)
{
	int i, j, k;
	int c;										//权值定义,不要可忽略
	char v1, v2;
	ArcNode *p1;								//p1指向头结点连接的边结点
  //ArcNode *p2;								//p2指向边结点连接的头结点,有向邻接表可以省略,无向输入a->b,默认补充b->a.
	printf_s("输入总顶点数和总边数:");
	scanf_s("%d %d", &G->vexnum, &G->arcnum);	//输入总结点数和边数
	printf_s("输入各个顶点的值:");
	fflush(stdin);
	for (i = 0; i < G->vexnum; i++)
	{
		scanf_s("%c", &G->vextices[i].data);	//数组的头结点初始化
		G->vextices[i].firstarc = NULL;
	}
	for (k = 0; k < G->arcnum; k++)
	{
		fflush(stdin);
		printf_s("输入相连的两边(请一条边一条边输入):");
		v1 = getchar();							//输入两个连接点如 “a b”,scanf_s("%c %c",&v1,&v2)在Vs中V2不能读入,vc中可以三个输入直接scanf。
		getchar();								//吃一个空格
		v2 = getchar();
		getchar();
		scanf_s("%d",&c);						//输入权值
		i = LocateVex(G, v1);					//得到输入编号在数组中对应的下标
		j = LocateVex(G, v2);
		//printf_s("\n%d %d %c %c\n",i,j,v1,v2);
		p1 = (ArcNode *)malloc(sizeof(ArcNode));
		p1->adjvex = j;
		p1->info = c;
		/*			
		p1->nextarc = NULL;						//尾插法存储连接
		ArcNode *p;
		p = G->vextices[i].firstarc;
		if (p == NULL)
		{
			G->vextices[i].firstarc = p1;
		}
		else
		{
			while (p->nextarc)
			{
				p = p->nextarc;
			}
			p->nextarc = p1;
		}
		*/

		
		p1 = (ArcNode *)malloc(sizeof(ArcNode));//头插法存储连接
		p1->adjvex = j;
		p1->info = c;							//权值赋值
		p1->nextarc = G->vextices[i].firstarc;
		G->vextices[i].firstarc = p1;
		

		/*
		p2 = (ArcNode *)malloc(sizeof(ArcNode));//有向邻接表忽略这部分
		p2->adjvex = i;
		p2->nextarc = G->vextices[j].firstarc;
		G->vextices[j].firstarc = p2;
		*/
	}
}
void DisGraph(ALGraph *G)
{
	int i;
	ArcNode *p;
	for (i = 0; i < G->vexnum; i++)
	{
		p = G->vextices[i].firstarc;
		printf_s("%c->", G->vextices[i].data);
		while (p != NULL)
		{
		  //printf_s("%c->", G->vextices[p->adjvex].data);				//无权值输入
			printf_s("%c(%d)->", G->vextices[p->adjvex].data,p->info);	//有权值输入
			p = p->nextarc;
		}
		printf_s("NULL\n");
	}
}
void main()
{
	ALGraph *G=(ALGraph*)malloc(sizeof(ALGraph));
	CreateUDG(G);
	DisGraph(G);
}

  • 4
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
好的,以下是C语言代码示例,演示了如何通过邻接矩阵输入尾插法建立邻接表: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTEX_NUM 20 // 最大顶点数 // 邻接表结点 typedef struct Node { int adjvex; // 邻接点下标 struct Node *next; // 指向下一个邻接点的指针 } Node; // 顶点 typedef struct Vertex { int data; // 顶点值 Node *first; // 指向第一个邻接点的指针 } Vertex; // 邻接表 typedef struct { Vertex vertices[MAX_VERTEX_NUM]; // 顶点数组 int vexnum, arcnum; // 顶点数和边数 } Graph; // 初始化邻接表 void InitGraph(Graph *G, int vexnum) { G->vexnum = vexnum; G->arcnum = 0; for (int i = 0; i < vexnum; i++) { G->vertices[i].data = i; // 顶点值 G->vertices[i].first = NULL; // 指向第一个邻接点的指针 } } // 插入边 void InsertArc(Graph *G, int v1, int v2) { Node *p = (Node*)malloc(sizeof(Node)); p->adjvex = v2; p->next = G->vertices[v1].first; G->vertices[v1].first = p; G->arcnum++; } // 创建邻接表 void CreateGraph(Graph *G) { int v1, v2; printf("请输入顶点数和边数:"); scanf("%d%d", &G->vexnum, &G->arcnum); for (int i = 0; i < G->arcnum; i++) { printf("请输入边(vi,vj)的顶点序号:"); scanf("%d%d", &v1, &v2); InsertArc(G, v1, v2); } } // 打印邻接表 void PrintGraph(Graph *G) { printf("邻接表如下:\n"); for (int i = 0; i < G->vexnum; i++) { printf("%d", G->vertices[i].data); Node *p = G->vertices[i].first; while (p) { printf("->%d", G->vertices[p->adjvex].data); p = p->next; } printf("\n"); } } int main() { Graph G; CreateGraph(&G); PrintGraph(&G); return 0; } ``` 希望这个代码示例能够帮助您更好地理解邻接矩阵输入尾插法建立邻接表的过程。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

madkeyboard

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值