1. 程式人生 > >圖的鄰接表表示

圖的鄰接表表示

描述

圖的表示除了鄰接矩陣表示,還可以使用連結串列陣列。對每個頂點(表頭節點)建立一個單鏈表,第i個單鏈表中節點表示依附於頂點vi 的邊(對有向圖而言,是以頂點vi為尾的弧)。所以在鄰接表中,除了節點外,還有表頭節點。

兩種方法比較

假設圖有V個頂點,E條邊。空間權衡方面,鄰接矩陣使用的空間正比於V^2;而鄰接表所使用的空間正比於V+E。如果邊數較少(也叫稀疏圖),則優先選用鄰接表。若大多數頂點對都由邊相接(也叫稠密圖),則使用鄰接矩陣,避免為不存在的邊分配任何空間。在複雜度方面,鄰接矩陣表示可以在O(n)時間內解決“頂點i和頂點j之間是否存在有邊” 的問題。其他的時候,用鄰接表表示更有效,允許在正比於V+E的時間內而不是V^2的時間內遍歷圖的所有邊

資料結構定義

這裡寫圖片描述

程式碼實現

#include <iostream>
using namespace std;

#include <stdio.h>
#include <stdlib.h>

#define Max_Vertex_Num  100   //最大頂點數

typedef char VertexType;      //頂點數型別定義
typedef int EdgeType;        //邊型別定義

typedef struct EdgeNode
{
    int adjvex;               // 該邊所指的頂點的位置
    EdgeType weight;          //該邊的權值
struct EdgeNode *NextEdge; //指向下一條邊的指標 }EdgeNode; typedef struct VertexNode { VertexType data; // 頂點資訊 EdgeNode *firstEdge; //指向第一條依附該頂點的邊表頭指標 }VertexNode, AdjList[Max_Vertex_Num]; typedef struct { AdjList adjList; int EdgeNum; // 圖的當前邊數 int VertexNum; //圖的當前頂點數 }ALGraph; // 返回頂點v的位置
int LocateVertex(ALGraph *G, VertexType v) { int i = 0; for(i = 0; v != G->adjList[i].data && i < G->VertexNum; i ++); if(i >= G->VertexNum) return -1; return i; } //增加節點 void AddVertex(ALGraph *G) { cout << "input vertex number" << endl; cin >> G->VertexNum; cout << "input vertex value" << endl; for(int i = 0; i < G->VertexNum; i++) { cin >> G->adjList[i].data; G->adjList[i].firstEdge = NULL; } } //增加邊表 void AddEdge(ALGraph *G) { cout << "input edge number" << endl; cin >> G->EdgeNum ; VertexType V1, V2; cout << "input two vertex" << endl; for(int k = 0; k < G->EdgeNum; k ++) { cin >> V1 >> V2; int i = LocateVertex(G,V1); int j = LocateVertex(G,V2); EdgeNode *pe1 = (EdgeNode *)malloc(sizeof(EdgeNode)); pe1->adjvex = i; pe1->NextEdge = G->adjList[j].firstEdge; G->adjList[j].firstEdge = pe1; EdgeNode *pe2 = (EdgeNode *)malloc(sizeof(EdgeNode)); pe2->adjvex = j; pe2->NextEdge = G->adjList[i].firstEdge; G->adjList[i].firstEdge = pe2; } } void CreatALGraph(ALGraph *G) { AddVertex(G); AddEdge(G); } void PrintALGrap(ALGraph *G) { EdgeNode *pe; cout << "編號 頂點 鄰點編號" << endl; for(int i = 0; i < G->VertexNum; i ++) { cout << " " << i << " " << G->adjList[i].data << " "; for(pe = G->adjList[i].firstEdge; pe; pe = pe->NextEdge) cout << pe->adjvex << " "; cout << endl; } } int main() { ALGraph GL; CreatALGraph(&GL); PrintALGrap(&GL); }