1. 程式人生 > >【圖(上)】小白專場:如何建立圖

【圖(上)】小白專場:如何建立圖

1、用鄰接矩陣表示圖

在這裡插入圖片描述

typedef struct GNode *PtrToGNode;
struct GNode
{
	int Nv; 		//頂點數
	int Ne; 		//邊數
	DataType Data[MaxVertexNum]; //存頂點的資料
};
typedef PtrToGNode MGraph; 	//以鄰接矩陣儲存的圖型別

MGraph初始化

  • 初始化一個有VertexNum個頂點但沒有邊的圖
typedef int Vertex; //用頂點下標表示頂點,為整型
MGraph CreateGraph(int VertexNum)
{
	Vertex V,
W; MGraph Graph; Graph = (MGraph)malloc(sizeof(struct GNode)); Graph->Nv = VertexNum; Graph->Ne = 0; /* 注意:這裡預設頂點編號從0開始,到(Graph->Nv - 1) */ for (V = 0; V<Graph->Nv; V++) for (W = 0; W<Graph->Nv; W++) Graph->G[V][W] = 0; //或INFINITY return Graph; }

向MGraph中插入邊

typedef
struct ENode *PtrToENode; struct ENode { Vertex V1, V2; //有向邊<V1, V2> WeightType Weight; //權重 }; typedef PtrToENode Edge; void InsertEdge(MGraph Graph, Edge E) { Graph->G[E->V1][E->V2] = E->Weight;//插入邊<V1, V2> Graph->G[E->V2][E->V1] = E->Weight;//若是無向圖,還要插入邊<V2, V1>
}

完整地建立一個MGraph

  • 輸入格式
    Nv Ne
    V1 V2 Weight
    ……
MGraph BuildGraph()
{
	MGraph Graph;
	Edge E;
	Vertex V;
	int Nv, i;

	scanf("%d", &Nv);
	Graph = CreateGraph(Nv);
	scanf("%d", &(Graph->Ne));
	if (Graph->Ne != 0)
	{
		E = (Edge)malloc(sizeof(struct ENode));
		for (i = 0; i<Graph->Ne; i++)
		{
			scanf("%d %d %d",&E->V1, &E->V2, &E->Weight);
			InsertEdge(Graph, E);
		}
	}
	//如果頂點有資料的話,讀入資料
	for (V = 0; V<Graph->Nv; V++)
		scanf(" %c", &(Graph->Data[V]));
	return Graph;
}

簡單方法實現用鄰接矩陣表示圖的建立

int G[MAXN][MAXN], Nv, Ne;
void BuildGraph()
{
	int i, j, v1, v2, w;
	scanf("%d", &Nv);
	//CreateGraph
	for (i = 0; i<Nv; i++)
		for (j = 0; j<Nv; j++)
			G[i][j] = 0; //或INFINITY
	scanf("%d", &Ne);
	for (i = 0; i<Ne; i++)
	{
		scanf("%d %d %d", &v1, &v2, &w);
		//InsertEdge
		G[v1][v2] = w;
		G[v2][v1] = w;
	}
}

此種方法的缺點,這種建立方法只適用於用鄰接矩陣表示圖,若換一種表示方法,就不適用了,不推薦

2、用鄰接表表示圖

  • 鄰接表:G[N]為指標陣列,對應矩陣每行一個連結串列,只存非0元素
    在這裡插入圖片描述
typedef struct Vnode
{
	PtrToAdjVNode FirstEdge;
	DataType Data; //存頂點的資料
} AdjList[MaxVertexNum];
//AdjList是鄰接表型別,
//有幾個頂點就有幾個連結串列,每一個連結串列開始於一個結點和一個指標

typedef struct GNode *PtrToGNode;
struct GNode
{
	int Nv; 	//頂點數
	int Ne; 	//邊數
	AdjList G;	//鄰接表
};
typedef PtrToGNode LGraph;
//以鄰接表方式儲存的圖型別,包括有頂點,邊和鄰接表

typedef struct AdjVNode *PtrToAdjVNode;
struct AdjVNode {
	Vertex AdjV; 	//鄰接點下標
	WeightType Weight; //邊權重
	PtrToAdjVNode Next;
};

LGraph初始化

  • 初始化一個有VertexNum個頂點但沒有邊的圖
typedef int Vertex; //用頂點下標表示頂點,為整型
LGraph CreateGraph(int VertexNum)
{
	Vertex V, W;
	LGraph Graph;
	Graph = (LGraph)malloc(sizeof(struct GNode));
	Graph->Nv = VertexNum;
	Graph->Ne = 0;
	//注意:這裡預設頂點編號從0開始,到(Graph->Nv - 1)
	for (V = 0; V<Graph->Nv; V++)
		Graph->G[V].FirstEdge = NULL;
	return Graph;
}

向LGraph中插入邊

在這裡插入圖片描述

void InsertEdge(LGraph Graph, Edge E)
{
	PtrToAdjVNode NewNode;
	/************* 插入邊<V1, V2> ************/
	//為V2建立新的鄰接點
	NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode->AdjV = E->V2;
	NewNode->Weight = E->Weight;
	//將V2插入V1的表頭
	NewNode->Next = Graph->G[E->V1].FirstEdge;
	Graph->G[E->V1].FirstEdge = NewNode;
	/****** 若是無向圖,還要插入邊<V2, V1> ******/
	//為V1建立新的鄰接點
	NewNode = (PtrToAdjVNode)malloc(sizeof(struct AdjVNode));
	NewNode->AdjV = E->V1;
	NewNode->Weight = E->Weight;
	//將V1插入V2的表頭
	NewNode->Next = Graph->G[E->V2].FirstEdge;
	Graph->G[E->V2].FirstEdge = NewNode;
}

完整地建立一個LGraph

同完整地建立一個MGraph相同