1. 程式人生 > >圖之無向鄰接表

圖之無向鄰接表

這是用連結串列的方式來儲存無向圖,把每條邊類比成指向下個頂點的指標來儲存,

     在用連結串列儲存時,要注意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;
}