一個無向圖G,五個頂點,8條邊,用鄰接表形式表示該圖
那麼該如何用C語言來表達呢?
首先看看我們的無向圖的頭文件ALGraph.h
其中最關鍵的是邊表和頂點表
邊表是關聯頂點與其他頂點之間的關聯
而頂點表是一個數組,保存所有的頂點,每個頂點內保存着頂點編號、權值 以及 邊表頭
聰明的你不難看出,這其實類似一個二維數組,只不過最裏層的是一個不定長數組
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifndef ALGRAPH_H_INCLUDED
#define ALGRAPH_H_INCLUDED
#define MAXVERTEXNUM 1000 //最大頂點數
//定義一個頂點類型
typedef unsigned char VertexType;
typedef unsigned char WeightType;
//邊表結點
typedef struct EDGENODE
{
int adjVertex;//邊編號
struct EDGENODE * nextNode;
} EdgeNode;
//頂點表結點
typedef struct VERTEXNODE
{
VertexType vertex; //頂點值
WeightType weight;//權值
EdgeNode * FirstEdge;//第一邊結點
} VertexNode;
//頂點表類型
typedef VertexNode AdjList[MAXVERTEXNUM];
//圖
typedef struct ALGRAPH
{
AdjList adjlist;
int VertexNum;//頂點數
int EdgeNum;//邊數
} ALGraph;
/**
* 函數的定義
*/
//圖的初始化
int ALGraph_init(ALGraph ** pg);
//創建圖
int Create_ALGraph(ALGraph * g);
//輸出圖結構
void Output_ALGraph(ALGraph *g);
#endif // ALGRAPH_H_INCLUDED
接下來是源文件ALGraph.c,用於實現創建圖等操作,重要地方都有註釋,最後遍歷鄰接表的方法類似二維不定長數組的遍歷
#include "ALGraph.h"
//圖的初始化
int ALGraph_init(ALGraph ** pg)
{
*pg = (ALGraph *)malloc(sizeof(ALGraph));
if(*pg==NULL)//內存分配失敗
{
return -1;
}
memset(*pg,0,sizeof(ALGraph));//內存內容全部填充爲0
return 0;
}
//創建圖
int Create_ALGraph(ALGraph * g)
{
if(g==NULL)
{
printf("創建圖時發現錯誤,未完成初始化操作!\n");
return -1;
}
printf("請輸入頂點數: ");
scanf("%d",&(g->VertexNum));
fflush(stdin);
printf("請輸入邊數: ");
scanf("%d",&(g->EdgeNum));
fflush(stdin);
if(g->EdgeNum < g->VertexNum - 1) // N個結點至少需要N-1條邊
{
printf("邊數的值不合法!\n");
return -1;
}
//*****************************************************************
printf("開始創建頂點表vertexlist\n");
int n;
for(n=0; n<g->VertexNum; n++)
{
fflush(stdin);
printf("vertexlist 第%d項是V",n);
scanf("%d",&(g->adjlist[n].vertex)); //取值範圍爲0-65535
g->adjlist[n].weight = 0;
g->adjlist[n].FirstEdge = NULL;
}
printf("創建頂點表完成!\n");
//*****************************************************************
EdgeNode * p = NULL;
printf("\n開始創建邊表edgelist\n");
int i,j;
for(n=0; n<g->EdgeNum; n++)
{
fflush(stdin);
printf("請輸入邊(Vi,Vj)的頂點序號:");
scanf("%d,%d",&i,&j);
if(i<0 || j<0||i>(g->VertexNum)||j>(g->VertexNum))
{
printf("輸入的值存在非法,操作失敗!\n");
return -1;
}
//在g->adjlist[i]處建立與j的關係
p = (EdgeNode *)malloc(sizeof(EdgeNode));
if(p==NULL)
{
printf("初始化結構體EdgeNode變量p失敗");
return -1;
}
p->adjVertex = j;
p->nextNode = g->adjlist[i].FirstEdge;
g->adjlist[i].FirstEdge = p;
//在g->adjlist[j]處建立與i的關係
p = (EdgeNode *)malloc(sizeof(EdgeNode));
if(p==NULL)
{
printf("初始化結構體EdgeNode變量p失敗");
return -1;
}
p->adjVertex = i;
p->nextNode = g->adjlist[j].FirstEdge;
g->adjlist[j].FirstEdge = p;
}
printf("創建邊表完成!\n");
return 0;
}
//輸出圖結構
void Output_ALGraph(ALGraph *g)
{
printf("\n鄰接表輸出如下: \n");
EdgeNode * p;
int n;
for(n=0 ; n<g->VertexNum ; n++)
{
printf("%d ",g->adjlist[n].vertex);//輸出頂點值
p = g->adjlist[n].FirstEdge;
while(p!=NULL)
{
printf("->");
printf("%d ",p->adjVertex);
p = p->nextNode;
}
printf("\n");
}
}
我們最重要的main方法
#include "ALGraph.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *arg[])
{
printf("嘗試將一個無向圖轉爲一個鄰接表!\n\n");
int ret;
ALGraph *g = NULL;
ret = ALGraph_init(&g);//初始化鄰接表內存區
if(ret<0)
{
perror("初始化圖時發現錯誤:沒有完成初始化操作\n");
return -1;
}
ret = Create_ALGraph(g);//創建鄰接表
if(ret<0)
{
printf("創建鄰接表失敗!\n");
return -1;
}
Output_ALGraph(g);//輸出鄰接表
return 0;
}