大話資料結構之圖
阿新 • • 發佈:2021-01-13
typedef char VertexType; /* 頂點型別應由使用者定義 */
typedef int EdgeType; /* 邊上的權值型別應由使用者定義 */
#define MAXVEX 100 /* 最大頂點數,應由使用者定義 */
#define INFINITY 65535 /* 用65535來代表∞ */
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]; /* 因為是無向圖,矩陣對稱 */
}
}
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];
``
```c
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 */
}
}
#define MAXVEX 9
Boolean visited[MAXVEX]; /* 訪問標誌的陣列 */
/* 鄰接矩陣的深度優先遞迴演算法 */
void DFS(MGraph G, int i)
{
int j;
visited[i] = TRUE;
printf("%c ", G.vexs[i]); /* 列印頂點,也可以其它操作 */
for(j = 0; j < G.numVertexes; j++)
if(G.arc[i][j] == 1 && !visited[j])
DFS(G, j); /* 對為訪問的鄰接頂點遞迴呼叫 */
}
/* 鄰接矩陣的深度遍歷操作 */
void DFSTraverse(MGraph G)
{
int i;
for(i = 0; i < G.numVertexes; i++)
visited[i] = FALSE; /* 初始所有頂點狀態都是未訪問過狀態 */
for(i = 0; i < G.numVertexes; i++)
if(!visited[i]) /* 對未訪問過的頂點呼叫DFS,若連通圖僅執行一次 */
DFS(G, i);
}
/* 鄰接表的深度優先遞迴演算法 */
void DFS(GraphAdjList GL, int i)
{
EdgeNode *p;
visited[i] = TRUE;
printf("%c ",GL->adjList[i].data); /* 列印頂點,也可以其它操作 */
p = GL->adjList[i].firstedge;
while(p)
{
if(!visited[p->adjvex])
DFS(GL, p->adjvex); /* 對為訪問的鄰接頂點遞迴呼叫 */
p = p->next;
}
}
/* 鄰接表的深度遍歷操作 */
void DFSTraverse(GraphAdjList GL)
{
int i;
for(i = 0; i < GL->numVertexes; i++)
visited[i] = FALSE; /* 初始所有頂點狀態都是未訪問過狀態 */
for(i = 0; i < GL->numVertexes; i++)
if(!visited[i]) /* 對未訪問過的頂點呼叫DFS,若是連通圖,只會執行一次 */
DFS(GL, i);
}
/* 鄰接矩陣的廣度遍歷演算法 */
void BFSTraverse(MGraph G)
{
int i, j;
Queue Q;
for(i = 0; i < G.numVertexes; i++)
visited[i] = FALSE;
InitQueue(&Q); /* 初始化一輔助用的佇列 */
for(i = 0; i < G.numVertexes; i++) /* 對每一個頂點做迴圈 */
{
if (!visited[i]) /* 若是未訪問過就處理 */
{
visited[i]=TRUE; /* 設定當前頂點訪問過 */
printf("%c ", G.vexs[i]); /* 列印頂點,也可以其它操作 */
EnQueue(&Q,i); /* 將此頂點入佇列 */
while(!QueueEmpty(Q)) /* 若當前佇列不為空 */
{
DeQueue(&Q,&i); /* 將隊對元素出佇列,賦值給i */
for(j=0;j<G.numVertexes;j++)
{
/* 判斷其它頂點若與當前頂點存在 */
/* 邊且未訪問過 */
if(G.arc[i][j] == 1 && !visited[j])
{
visited[j]=TRUE; /* 將找到的此頂點標記為已訪問 */
printf("%c ", G.vexs[j]); /* 列印頂點 */
EnQueue(&Q,j); /* 將找到的此頂點入佇列 */
}
}
}
}
}
}
/* 鄰接表的廣度遍歷演算法 */
void BFSTraverse(GraphAdjList GL)
{
int i;
EdgeNode *p;
Queue Q;
for(i = 0; i < GL->numVertexes; i++)
visited[i] = FALSE;
InitQueue(&Q);
for(i = 0; i < GL->numVertexes; i++)
{
if (!visited[i])
{
visited[i]=TRUE;
printf("%c ",GL->adjList[i].data); /* 列印頂點,也可以其它操作 */
EnQueue(&Q,i);
while(!QueueEmpty(Q))
{
DeQueue(&Q,&i);
p = GL->adjList[i].firstedge; /* 找到當前頂點的邊錶鏈表頭指標 */
while(p)
{
if(!visited[p->adjvex]) /* 若此頂點未被訪問 */
{
visited[p->adjvex]=TRUE;
printf("%c ",GL->adjList[p->adjvex].data);
EnQueue(&Q,p->adjvex); /* 將此頂點入佇列 */
}
p = p->next; /* 指標指向下一個鄰接點 */
}
}
}
}
}