一 . 鄰接矩陣
圖的鄰接矩陣存儲方式是用兩個數組來表示圖,一個一維數組來存儲頂點信息,一個二維數組存儲圖中的邊或弧的信息
數據類型
#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)頂點數+邊數
對於邊少頂點多(稀疏圖)使用領接表創建,邊多頂點少(稠密圖)用鄰接矩陣創建。