【資料結構】資料結構C語言的實現【圖(鄰接表法)】
阿新 • • 發佈:2019-01-30
圖(鄰接表法)
/*
* 鄰接表的建立和圖的遍歷的程式碼實現
*/
#include <stdio.h>
#include <stdlib.h>
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
#define MAX_NUM 20
typedef int Status;
typedef int QElemType;
typedef char VexType;
/*
* 鄰接表儲存結構
*/
typedef struct EdgeNode
{
int adjvex; // 頂點的位置
struct EdgeNode *next; // 指向下一條邊的指標
} EdgeNode, *EdgeLink;
typedef struct VexNode
{
VexType data; // 頂點資料
EdgeNode *firstEdge; // 指向第一條依附該頂點的邊的指標
} VexNode, AdjList[MAX_NUM];
typedef struct
{
AdjList adjList;
int vexNum, edgeNum; // 頂點數和邊數
} ALGraph;
/*
* 佇列儲存結構(用於圖的遍歷)
*/
typedef struct QNode
{
QElemType data; //結點資料
struct QNode *next; //指向下一個結點
} QNode, *QueuePtr;
typedef struct
{
QueuePtr front; //隊頭指標
QueuePtr rear; //隊尾指標
} LinkQueue;
Status InitQueue(LinkQueue *Q)
{
Q->front = Q->rear = (QueuePtr)malloc(sizeof(QNode));
if (!Q->front)
exit (OVERFLOW);
Q->front->next = NULL;
return OK;
}
Status IsEmpty(LinkQueue Q)
{
if (Q.front->next == NULL)
return TRUE;
else
return FALSE;
}
Status EnQueue(LinkQueue *Q, QElemType e)
{
QueuePtr p = (QueuePtr)malloc(sizeof(QNode));
if (!p)
exit(OVERFLOW);
p->data = e;
p->next = NULL;
Q->rear->next = p;
Q->rear = p;
return OK;
}
Status DeQueue(LinkQueue *Q, QElemType *e)
{
QueuePtr p;
if (Q->front == Q->rear)
return ERROR;
p = Q->front->next;
*e = p->data;
Q->front->next = p->next;
if (Q->rear == p)
Q->rear = Q->front;
free(p);
return OK;
}
Status CreateGraph(ALGraph *G)
{
int i, j, k;
EdgeLink e;
printf("請輸入頂點數目和邊數:\n");
scanf("%d", &G->vexNum);
scanf("%d", &G->edgeNum);
getchar();
printf("請輸入各頂點的資料:\n");
for (i = 0; i < G->vexNum; i++)
{
scanf("%c", &G->adjList[i].data);
if (G->adjList[i].data == '\n')
{
i--;
continue;
}
G->adjList[i].firstEdge = NULL;
}
printf("請依次輸入邊(Vi,Vj)的頂點序號:\n");
for (k = 0; k < G->edgeNum; k++)
{
scanf("%d", &i);
scanf("%d", &j);
e = (EdgeLink)malloc(sizeof(EdgeNode));
e->adjvex = j;
e->next = G->adjList[i].firstEdge;
G->adjList[i].firstEdge = e;
e = (EdgeLink)malloc(sizeof(EdgeNode));
e->adjvex = i;
e->next = G->adjList[j].firstEdge;
G->adjList[j].firstEdge = e;
}
return OK;
}
int visited[MAX_NUM]; //用於記錄遍歷狀態
/*
* 遞迴從第i個結點深度優先遍歷圖
*/
void DFS(ALGraph G, int i)
{
EdgeLink p;
visited[i] = TRUE;
printf("%c ", G.adjList[i].data);
p = G.adjList[i].firstEdge;
while (p)
{
if (!visited[p->adjvex])
DFS(G, p->adjvex);
p = p->next;
}
}
/*
* 深度優先遍歷
*/
Status DFSTraverse(ALGraph G)
{
int i;
for (i = 0; i < MAX_NUM; i++)
visited[i] = FALSE;
for (i = 0; i < G.vexNum; i++)
{
if (!visited[i])
DFS(G, i);
}
return OK;
}
/*
* 廣度優先遍歷
*/
Status BFSTraverse(ALGraph G)
{
int i;
EdgeLink p;
LinkQueue Q;
InitQueue(&Q);
for (i = 0; i < MAX_NUM; i++)
visited[i] = FALSE;
for (i = 0; i < G.vexNum; i++)
{
if (!visited[i])
{
visited[i] = TRUE;
printf("%c ", G.adjList[i].data);
EnQueue(&Q, i);
while (!IsEmpty(Q))
{
DeQueue(&Q, &i);
p = G.adjList[i].firstEdge;
while (p)
{
if (!visited[p->adjvex])
{
visited[p->adjvex] = TRUE;
printf("%c ", G.adjList[p->adjvex].data);
EnQueue(&Q, p->adjvex);
}
p = p->next;
}
}
}
}
return OK;
}
int main()
{
ALGraph G;
CreateGraph(&G);
printf("深度優先遍歷:");
DFSTraverse(G);
printf("\n廣度優先遍歷:");
BFSTraverse(G);
printf("\n");
}