图的邻接表表示法(C语言)

邻接表

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

#define  MaxVertices 100
typedef struct node{   //边表 
   int adjvex;
   node* next;  
}EdgeNode;  
  
typedef struct{     //顶点表  
   int vertex;  
   EdgeNode* edgenext;  
}VertexNode;  
  
typedef VertexNode AdjList[MaxVertices];//顶点表数组  
  
typedef struct{   
    AdjList adjlist;  
    int n,e;  
}AdjMatrix; 

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

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


邻接表生成函数:

void CreateGraph(AdjMatrix* G)  
{  
    int i,j,k,w,v;  
    EdgeNode *s;  
    printf("输入顶点数和边数(中间以空格分开):");  
    scanf("%d%d",&G->n,&G->e);  
  
    printf("建立顶点表\n"); 
    for (i=0;i<G->n;i++)  
    {  
		//fflush(stdin);  
		//如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。
		//故而使用 fflush(stdin) 是不正确的。
		getchar(); 
		printf("请输入第%d个顶点的信息:",i+1);
		G->adjlist[i].vertex=getchar();
		G->adjlist[i].edgenext=NULL;  
    }  
	//前插法 
    printf("建立边表\n");  
    for (k=0;k<G->e;k++)  
    {  
       printf("输入有连接的顶点序号:");  
       scanf("%d%d",&i,&j); 
       i-=1;j-=1; //①
       //对于直接相连的进行编入(即对输入“0 1”时,在0对应的边表中编入1) 
       s=(EdgeNode*)malloc(sizeof(EdgeNode));  
       s->adjvex=j;//边表赋值 
       s->next=G->adjlist[i].edgenext;  
       G->adjlist[i].edgenext=s;  
       //对于间接相连的进行编入(即对输入“0 1”时,在1对应的边表中编入0)
       s=(EdgeNode*)malloc(sizeof(EdgeNode));  
       s->adjvex=i;  
       s->next=G->adjlist[j].edgenext;  
       G->adjlist[j].edgenext=s;  
    }  
}   

邻接表打印函数:

void DispGraph(AdjMatrix *G)
{
	int i;
	for (i=0;i<G->n;i++)  
    {  
        printf("%d->",i+1);  
        while(1)  
        {             
			if(G->adjlist[i].edgenext==NULL)
            {
            	printf("^");
				break;	
			}
            printf("%d->",G->adjlist[i].edgenext->adjvex+1);
            //②
            G->adjlist[i].edgenext=G->adjlist[i].edgenext->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;  
}EdgeNode;  
  
typedef struct{     //顶点表  
   int vertex;  
   EdgeNode* edgenext;  
}VertexNode;  
  
typedef VertexNode AdjList[MaxVertices];  
  
typedef struct{   
    AdjList adjlist;  
    int n,e;  
}AdjMatrix;  

void CreateGraph(AdjMatrix* G)  
{  
    int i,j,k,w,v;  
    EdgeNode *s;  
    printf("输入顶点数和边数(中间以空格分开):");  
    scanf("%d%d",&G->n,&G->e);  
  
    printf("建立顶点表\n"); 
    for (i=0;i<G->n;i++)  
    {  
		//fflush(stdin);  
		//如果 stream 指向输入流(如 stdin),那么 fflush 函数的行为是不确定的。
		//故而使用 fflush(stdin) 是不正确的。
		getchar(); 
		printf("请输入第%d个顶点的信息:",i+1);
		G->adjlist[i].vertex=getchar();
		G->adjlist[i].edgenext=NULL;  
    }  
	//前插法 
    printf("建立边表\n");  
    for (k=0;k<G->e;k++)  
    {  
       printf("输入有连接的顶点序号:");  
       scanf("%d%d",&i,&j);  
       i-=1;j-=1;//①
       //对于直接相连的进行编入(即对输入“0 1”时,在0对应的边表中编入1) 
       s=(EdgeNode*)malloc(sizeof(EdgeNode));  
       s->adjvex=j;//边表赋值 
       s->next=G->adjlist[i].edgenext;  
       G->adjlist[i].edgenext=s;  
       //对于间接相连的进行编入(即对输入“0 1”时,在1对应的边表中编入0)
       s=(EdgeNode*)malloc(sizeof(EdgeNode));  
       s->adjvex=i;  
       s->next=G->adjlist[j].edgenext;  
       G->adjlist[j].edgenext=s;  
    }  
}   
void DispGraph(AdjMatrix *G)
{
	int i;
	for (i=0;i<G->n;i++)  
    {  
        printf("%d->",i+1);  
        while(1)  
        {             
			if(G->adjlist[i].edgenext==NULL)
            {
            	printf("^");
				break;	
			}
            printf("%d->",G->adjlist[i].edgenext->adjvex+1); 
            //② 
            G->adjlist[i].edgenext=G->adjlist[i].edgenext->next;  
 
        }  
        printf("\n");  
    }  
} 
int main()  
{  
   AdjMatrix* G= (AdjMatrix*)malloc(sizeof(AdjMatrix));  
   CreateGraph(G);  
   DispGraph(G); 
}
  • 97
    点赞
  • 364
    收藏
    觉得还不错? 一键收藏
  • 9
    评论
邻接表是一种表示方法,它以每个节点为基础,对每个节点的相邻节点进行链式存储。邻接表由一个数组和一个链表组成,数组中每个元素对应一个节点,链表中则存储与该节点相邻的节点。以下是邻接表C语言实现: ```c #include <stdio.h> #include <stdlib.h> #define MAX_VERTEX_NUM 100 // 最大顶点数 // 边表结构体 typedef struct ArcNode { int adjvex; // 邻接点下标 struct ArcNode *nextarc; // 指向下一个邻接点的指针 } ArcNode; // 顶点表结构体 typedef struct { int data; // 顶点信息 ArcNode *first; // 指向第一个邻接点的指针 } VNode; // 结构体 typedef struct { VNode vertex[MAX_VERTEX_NUM]; // 顶点表 int vexnum; // 顶点数 int arcnum; // 边数 } ALGraph; // 遍历 void DFS(ALGraph *G, int v, int *visited) { printf("%d ", G->vertex[v].data); visited[v] = 1; // 标记当前节点已被访问 ArcNode *p = G->vertex[v].first; while (p != NULL) { if (visited[p->adjvex] == 0) { DFS(G, p->adjvex, visited); } p = p->nextarc; } } // 创建 void CreateGraph(ALGraph *G) { printf("请输入顶点数和边数:"); scanf("%d %d", &G->vexnum, &G->arcnum); for (int i = 0; i < G->vexnum; i++) { printf("请输入第 %d 个顶点信息:", i + 1); scanf("%d", &G->vertex[i].data); G->vertex[i].first = NULL; } for (int i = 0; i < G->arcnum; i++) { printf("请输入第 %d 条边的起点和终点:", i + 1); int start, end; scanf("%d %d", &start, &end); ArcNode *p = (ArcNode *)malloc(sizeof(ArcNode)); p->adjvex = end - 1; p->nextarc = G->vertex[start - 1].first; G->vertex[start - 1].first = p; } } int main() { ALGraph G; CreateGraph(&G); int visited[MAX_VERTEX_NUM] = {0}; // 记录节点是否被访问过的数组 printf("DFS遍历结果为:"); for (int i = 0; i < G.vexnum; i++) { if (visited[i] == 0) { DFS(&G, i, visited); } } return 0; } ``` 在上面的代码中,我们定义了两个结构体,分别是顶点表结构体和边表结构体。创建时,我们先输入顶点数和边数,然后依次输入每个顶点的信息,再输入每条边的起点和终点,将边加入到邻接表中。遍历时,我们使用DFS算法进行遍历,从每个未被访问过的节点开始递归遍历其相邻节点。
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值