#include "stdio.h"
#include "stdlib.h"
#include "stdbool.h"
#define MaxVertex 10
typedef int datatype_t;
typedef struct node {
datatype_t data;
struct node *next;
} linknode_t;
typedef struct {
linknode_t *front;
linknode_t *rear;
} linkqueue_t;
typedef char ElemType;
typedef struct Node { //链表中的值
int nextVertex;//指向的位置
struct Node *next;
} Node;
struct HeadNode {//链表头
ElemType data;
struct Node *next;
};
typedef struct AdjacencyGraph {
int vertexCount;//顶点数
int edgeCount;//边数
struct HeadNode vertex[MaxVertex];//顶点数组
} Graph;
linkqueue_t *linkqueue_create() {
linkqueue_t *queue = (linkqueue_t *) malloc(sizeof(linkqueue_t));
if (queue == NULL) {
exit(-1);
}
queue->front = queue->rear = (linknode_t *) malloc(sizeof(linknode_t));
if (queue->front == NULL) {
exit(-1);
}
queue->front->next = NULL;
return queue;
}
//入队
int linkqueue_enter(linkqueue_t *queue, datatype_t value) {
linknode_t *temp = (linknode_t *) malloc(sizeof(linknode_t));
if (temp == NULL) {
return -1;
}
temp->data = value;
temp->next = NULL;
queue->rear->next = temp;
queue->rear = temp;
return 1;
}
//判断队列是否为空
int linkqueue_empty(linkqueue_t *queue) {
return queue->front == queue->rear ? 1 : 0;
}
datatype_t linkqueue_out(linkqueue_t *queue) {
if (linkqueue_empty(queue)) {
return -1;
}
linknode_t *temp = queue->front;
queue->front = queue->front->next;
datatype_t value = queue->front->data;
free(temp);
temp = NULL;
return value;
}
Graph *create_graph() {
Graph *graph = (Graph *) malloc(sizeof(Graph));
if (graph == NULL) {
exit(-1);
}
graph->vertexCount = 0;
graph->edgeCount = 0;
return graph;
}
void insert_vertex(Graph *graph, ElemType data) {
if (graph->vertexCount >= MaxVertex) {
return;
}
graph->vertex[graph->vertexCount].data = data;
graph->vertex[graph->vertexCount].next = NULL;
graph->vertexCount++;
}
void insert_edge(Graph *graph, int a, int b) {
Node *node = graph->vertex[a].next;
Node *newNode = malloc(sizeof(struct Node));
newNode->next = NULL;
newNode->nextVertex = b;
if (node == NULL) {
graph->vertex[a].next = newNode;
} else {
do {
if (node->nextVertex == b) {
free(newNode);
break;
}
if (node->next) {
node = node->next;
} else {
break;
}
} while (1);
node->next = newNode;
}
graph->edgeCount++;
}
/**
* 广度优先搜索
* @param graph 有向图
* @param startVertex 开始顶点下标
* @param targetVertex 目标顶点下标
* @param visited 已经访问过的顶点
* @param queue 辅助队列
*/
bool bfs(Graph *graph, int startVertex, int targetVertex, int *visited, linkqueue_t *queue) {
linkqueue_enter(queue, startVertex);
visited[startVertex] = 1;
while (linkqueue_empty(queue) == 0) {
int next = linkqueue_out(queue);
printf("%c -> ", graph->vertex[next].data);
Node *node = graph->vertex[next].next;
while (node) {
if (node->nextVertex == targetVertex) {
return true;
}
if (visited[node->nextVertex] == 0) {
linkqueue_enter(queue, node->nextVertex);
visited[node->nextVertex] = 1;
}
node = node->next;
}
}
return false;
}
void printGraph(Graph *graph) {
for (int i = 0; i < graph->vertexCount; ++i) {
printf("%d | %c", i, graph->vertex[i].data);
Node *node = graph->vertex[i].next;
while (node) {
printf(" -> %d", node->nextVertex);
node = node->next;
}
putchar('\n');
}
}
int main() {
linkqueue_t *queue = linkqueue_create();
setbuf(stdout, NULL);
Graph *graph = create_graph();
for (int i = 'A'; i <= 'G'; ++i) {
insert_vertex(graph, (char) i);
}
insert_edge(graph, 0, 1);//A->B
insert_edge(graph, 1, 2);//B->C
insert_edge(graph, 1, 3);//B->D
insert_edge(graph, 1, 4);//B->E
insert_edge(graph, 4, 5);//E->F
insert_edge(graph, 3, 6);//D->G
printGraph(graph);
int arr[graph->vertexCount];
for (int i = 0; i < graph->vertexCount; ++i) {
arr[i] = 0;
}
printf("\n%d ", bfs(graph, 0, 5, arr, queue));
free(graph);
return 0;
}
运行效果