圖的創建(鄰接矩陣和領接表)

一 . 鄰接矩陣

圖的鄰接矩陣存儲方式是用兩個數組來表示圖,一個一維數組來存儲頂點信息,一個二維數組存儲圖中的邊或弧的信息

數據類型

#define MAXVEX 100 /* 最大頂點數,應由用戶定義 */

#define INFINITY 65535



typedef int Status;	/* Status是函數的類型,其值是函數結果狀態代碼,如OK等 */

typedef char VertexType; /* 頂點類型應由用戶定義  */

typedef int EdgeType; /* 邊上的權值類型應由用戶定義 */

typedef struct

{

	VertexType vexs[MAXVEX]; /* 頂點表 */

	EdgeType arc[MAXVEX][MAXVEX];/* 鄰接矩陣,可看作邊表 */

	int numNodes, numEdges; /* 圖中當前的頂點數和邊數  */

}MGraph;

存儲過程:

/* 建立無向網圖的鄰接矩陣表示 */

void CreateMGraph(MGraph *G)

{

	int i,j,k,w;

	printf("輸入頂點數和邊數:\n");

	scanf("%d,%d",&G->numNodes,&G->numEdges); /* 輸入頂點數和邊數 */

	for(i = 0;i <G->numNodes;i++) /* 讀入頂點信息,建立頂點表 */

		scanf(&G->vexs[i]);

	for(i = 0;i <G->numNodes;i++)

		for(j = 0;j <G->numNodes;j++)

			G->arc[i][j]=INFINITY;	/* 鄰接矩陣初始化 */

	for(k = 0;k <G->numEdges;k++) /* 讀入numEdges條邊,建立鄰接矩陣 */

	{

		printf("輸入邊(vi,vj)上的下標i,下標j和權w:\n");

		scanf("%d,%d,%d",&i,&j,&w); /* 輸入邊(vi,vj)上的權w */

		G->arc[i][j]=w; 

		G->arc[j][i]= G->arc[i][j]; /* 因爲是無向圖,矩陣對稱 */

	}

}

二 . 領接表

圖的領接表由邊表(用單鏈表構成)和頂點表(由一維數組構成)組成,這種創建方法類似樹的孩子表示法。

數據類型:

#define MAXVEX 100 /* 最大頂點數,應由用戶定義 */



typedef int Status;	/* Status是函數的類型,其值是函數結果狀態代碼,如OK等 */

typedef char VertexType; /* 頂點類型應由用戶定義 */

typedef int EdgeType; /* 邊上的權值類型應由用戶定義 */



typedef struct EdgeNode /* 邊表結點  */

{

	int adjvex;    /* 鄰接點域,存儲該頂點對應的下標 */

	EdgeType info;		/* 用於存儲權值,對於非網圖可以不需要 */

	struct EdgeNode *next; /* 鏈域,指向下一個鄰接點 */

}EdgeNode;



typedef struct VertexNode /* 頂點表結點 */

{

	VertexType data; /* 頂點域,存儲頂點信息 */

	EdgeNode *firstedge;/* 邊表頭指針 */

}VertexNode, AdjList[MAXVEX];



typedef struct

{

	AdjList adjList; 

	int numNodes,numEdges; /* 圖中當前頂點數和邊數 */

}GraphAdjList;

創建過程:

void  CreateALGraph(GraphAdjList *G)

{

	int i,j,k;

	EdgeNode *e;

	printf("輸入頂點數和邊數:\n");

	scanf("%d,%d",&G->numNodes,&G->numEdges); /* 輸入頂點數和邊數 */

	for(i = 0;i < G->numNodes;i++) /* 讀入頂點信息,建立頂點表 */

	{

		scanf(&G->adjList[i].data); 	/* 輸入頂點信息 */

		G->adjList[i].firstedge=NULL; 	/* 將邊表置爲空表 */

	}

	for(k = 0;k < G->numEdges;k++)/* 建立邊表 */

	{

		printf("輸入邊(vi,vj)上的頂點序號:\n");

		scanf("%d,%d",&i,&j); /* 輸入邊(vi,vj)上的頂點序號 */

		e=(EdgeNode *)malloc(sizeof(EdgeNode)); /* 向內存申請空間,生成邊表結點 */

		e->adjvex=j;					/* 鄰接序號爲j */                         

		e->next=G->adjList[i].firstedge;	/* 將e的指針指向當前頂點上指向的結點 */

		G->adjList[i].firstedge=e;		/* 將當前頂點的指針指向e */               

		

		e=(EdgeNode *)malloc(sizeof(EdgeNode)); /* 向內存申請空間,生成邊表結點 */

		e->adjvex=i;					/* 鄰接序號爲i */                         

		e->next=G->adjList[j].firstedge;	/* 將e的指針指向當前頂點上指向的結點 */

		G->adjList[j].firstedge=e;		/* 將當前頂點的指針指向e */               

	}

}

兩種方法的區別:鄰接矩陣時間複雜度爲O(N2) 邊數的平方 , 鄰接表時間複雜度O(N+E)頂點數+邊數

對於邊少頂點多(稀疏圖)使用領接表創建,邊多頂點少(稠密圖)用鄰接矩陣創建。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章