图之无向邻接表

     这是用链表的方式来储存无向图,把每条边类比成指向下个顶点的指针来存储,

     在用链表存储时,要注意2个地方:

     1.分清楚无向链表的层次,我用结构体的方式给出;

     2.在向首顶点添加下一顶点的时候,要注意是给首顶点加,还是给

     首顶点所在链表加。


     话不多说,一切看代码:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define nLENGTH(a)  (sizeof(a)/sizeof(a[0]))
#define eLENGTH(a) ( sizeof(a) / sizeof(char) )/ ( sizeof(a[0]) / sizeof(char) )
#define MAX 10
//单链后节点
typedef struct ENode{
	int eVex;
	struct ENode *next_edg;
}eNode,*PeNode;
//单链的第一个节点
typedef struct VNode{
	char elem;
	eNode *first_edg;
}vNode,*PvNode;

// 邻接表
typedef struct pGraph
{
    int vexnum;             // 图的顶点的数目
    int edgnum;             // 图的边的数目
	vNode vexs[MAX];
}Graph,*PGraph;


//指向节点的位置
int point_node(PGraph g,char c)
{
	for(int i=0;i<g->vexnum;i++)
	{
		if(g->vexs[i].elem==c)
		{
			return i;
		}
	}
	return -1;
}
//接到单链的下一个位置
static void link_last(PeNode f,PeNode node )
{
	
  eNode *p = f;//p指向当前顶点

 while(p->next_edg) //遍历到链的最后一个顶点的next_edg
        p = p->next_edg;
   p->next_edg = node;
/* while(p!=NULL)  //遍历到链的最后一个顶点,这是错误的地方。
	{
		p=p->next_edg;
	}
	p->next_edg=node;*/


//	printf("%d",f->eVex);
}
//建立邻接表
PGraph create_graph(char b[][2],char a[],int n,int e)
{
	char c1,c2; //边的2个顶点
	PGraph g; //矩阵
	g=(PGraph)malloc(sizeof(Graph));
	//memset()第一个参数 是地址,第二个参数是开辟空间的初始值,第三个参数是开辟空间的大小
	memset(g, 0, sizeof(Graph));
	printf("顶点个数:\n");//顶点数
	g->vexnum=n;
	printf("%d\n",g->vexnum);
	printf("边个数:\n");//边数
	g->edgnum=e;
	printf("%d\n",g->edgnum);
	//初始化顶点
	for(int j=0;j<g->vexnum;j++)
	{
		g->vexs[j].elem=a[j];
		g->vexs[j].first_edg=NULL;
	}

	for(int i=0;i<g->edgnum;i++)
	{
		
		int p1,p2;
		c1=b[i][0];
		c2=b[i][1];
		p1=point_node(g, c1);
		p2=point_node(g, c2);
		PeNode node1,node2;
		node1=(PeNode)malloc(sizeof(eNode));
		node1->eVex=p2;
		node1->next_edg=NULL;
		if(g->vexs[p1].first_edg==NULL)
		{
			g->vexs[p1].first_edg=node1;
		}else{										//当单链第一个顶点的边已被选中,则把这条边接到后边
			link_last(g->vexs[p1].first_edg, node1);
		}
		node2=(PeNode)malloc(sizeof(eNode));
		node2->eVex=p1;
		node2->next_edg=NULL;
		if(g->vexs[p2].first_edg==NULL)
		{
			g->vexs[p2].first_edg=node2;
		}else{										//当单链第一个顶点的边已被选中,则把这条边接到后边
			link_last(g->vexs[p2].first_edg, node2);
		}
	}
	return g;
}
//打印链表
void printGraph(PGraph g)
{
	int i=0;
	PeNode f;
	while(i < g->vexnum)
	{
		f=g->vexs[i].first_edg;
		printf("%c\t",g->vexs[i].elem);
		while(f)
		{
			printf("%d\t",f->eVex);
			f=f->next_edg;
		}
		printf("\n");
		i++;
	}

}
int main ()
{
	PGraph gp;
	//测试用例

	char a[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
    char b[][2] = {
        {'A', 'C'}, 
        {'A', 'D'}, 
        {'A', 'F'}, 
        {'B', 'C'}, 
        {'C', 'D'}, 
        {'E', 'G'}, 
        {'F', 'G'}}; 

	//测试用例

	int n=nLENGTH(a);
	int e=eLENGTH(b);
	gp=create_graph(b,a,n,e);
	printGraph(gp);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值