帮我详细解释这些代码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
// 最大节点数量(房间总数估算)
#define MAX_NODES 50
// 房间名称最大长度
#define NAME_LEN 10
// 全局变量控制是否开启调试模式
bool debug_mode = false;
// 图的邻接表表示:每个房间可以到达的其他房间
typedef struct Node {
char name[NAME_LEN];
struct Node* next;
} Node;
typedef struct Graph {
Node* vertices[MAX_NODES];
int num_vertices;
char vertex_names[MAX_NODES][NAME_LEN]; // 存储所有顶点名字便于查找索引
} Graph;
// 队列用于BFS
typedef struct Queue {
int items[MAX_NODES];
int front;
int rear;
} Queue;
// 栈用于DFS
typedef struct Stack {
int items[MAX_NODES];
int top;
} Stack;
// 函数声明
Graph* create_graph();
int add_vertex(Graph* g, const char* name);
Node* create_node(const char* name);
void add_edge(Graph* g, const char* from, const char* to);
Queue* create_queue();
void enqueue(Queue* q, int index);
int dequeue(Queue* q);
bool is_empty_queue(Queue* q);
Stack* create_stack();
void push(Stack* s, int index);
int pop(Stack* s);
bool is_empty_stack(Stack* s);
int find_index(Graph* g, const char* name);
void print_path(int parent[], int indexes[], int n, Graph* g);
void bfs(Graph* g, int start_idx);
void dfs(Graph* g, int start_idx);
// 创建图
Graph* create_graph() {
Graph* g = (Graph*)malloc(sizeof(Graph));
for (int i = 0; i < MAX_NODES; i++) {
g->vertices[i] = NULL;
}
g->num_vertices = 0;
return g;
}
// 添加新顶点并返回其索引
int add_vertex(Graph* g, const char* name) {
for (int i = 0; i < g->num_vertices; i++) {
if (strcmp(g->vertex_names[i], name) == 0) {
return i;
}
}
strcpy(g->vertex_names[g->num_vertices], name);
g->vertices[g->num_vertices] = NULL;
return g->num_vertices++;
}
// 创建邻接节点
Node* create_node(const char* name) {
Node* node = (Node*)malloc(sizeof(Node));
strcpy(node->name, name);
node->next = NULL;
return node;
}
// 添加无向边
void add_edge(Graph* g, const char* from, const char* to) {
int from_idx = find_index(g, from);
int to_idx = find_index(g, to);
Node* newNode = create_node(to);
newNode->next = g->vertices[from_idx];
g->vertices[from_idx] = newNode;
newNode = create_node(from);
newNode->next = g->vertices[to_idx];
g->vertices[to_idx] = newNode;
if (debug_mode) printf("Added edge: %s <-> %s\n", from, to);
}
// 查找顶点索引
int find_index(Graph* g, const char* name) {
for (int i = 0; i < g->num_vertices; i++) {
if (strcmp(g->vertex_names[i], name) == 0) {
return i;
}
}
return -1; // 不应该发生
}
// 创建队列
Queue* create_queue() {
Queue* q = (Queue*)malloc(sizeof(Queue));
q->front = -1;
q->rear = -1;
return q;
}
// 入队
void enqueue(Queue* q, int index) {
if (q->rear == MAX_NODES - 1) {
printf("Queue full!\n");
} else {
if (q->front == -1) q->front = 0;
q->rear++;
q->items[q->rear] = index;
}
}
// 出队
int dequeue(Queue* q) {
int item;
if (is_empty_queue(q)) {
return -1;
} else {
item = q->items[q->front];
q->front++;
if (q->front > q->rear) {
q->front = q->rear = -1;
}
}
return item;
}
// 判断队列为空
bool is_empty_queue(Queue* q) {
return q->front == -1;
}
// 创建栈
Stack* create_stack() {
Stack* s = (Stack*)malloc(sizeof(Stack));
s->top = -1;
return s;
}
// 压栈
void push(Stack* s, int index) {
if (s->top == MAX_NODES - 1) {
printf("Stack overflow!\n");
} else {
s->items[++s->top] = index;
}
}
// 弹栈
int pop(Stack* s) {
if (is_empty_stack(s)) {
return -1;
} else {
return s->items[s->top--];
}
}
// 判断栈为空
bool is_empty_stack(Stack* s) {
return s->top == -1;
}
// 打印路径
void print_path(int parent[], int indexes[], int goal_idx, Graph* g) {
int path[MAX_NODES];
int path_len = 0;
int current = goal_idx;
while (current != -1) {
path[path_len++] = current;
current = parent[current];
}
printf("Solution Path: ");
for (int i = path_len - 1; i >= 0; i--) {
printf("%s", g->vertex_names[path[i]]);
if (i > 0) printf(" -> ");
}
printf("\n");
}
// 广度优先搜索
void bfs(Graph* g, int start_idx) {
bool visited[MAX_NODES] = {false};
int parent[MAX_NODES];
Queue* q = create_queue();
for (int i = 0; i < g->num_vertices; i++) parent[i] = -1;
visited[start_idx] = true;
enqueue(q, start_idx);
if (debug_mode) printf("BFS started from %s\n", g->vertex_names[start_idx]);
while (!is_empty_queue(q)) {
int current_idx = dequeue(q);
char* current_name = g->vertex_names[current_idx];
if (debug_mode) printf("Exploring: %s\n", current_name);
// 目标检查:当前是否在 "Charger"
if (strcmp(current_name, "Charger") == 0) {
printf("Goal found!\n");
print_path(parent, NULL, current_idx, g);
free(q);
return;
}
// 遍历邻居
Node* neighbor = g->vertices[current_idx];
while (neighbor != NULL) {
int neighbor_idx = find_index(g, neighbor->name);
if (!visited[neighbor_idx]) {
visited[neighbor_idx] = true;
parent[neighbor_idx] = current_idx;
enqueue(q, neighbor_idx);
if (debug_mode) printf("Enqueued: %s (from %s)\n", neighbor->name, current_name);
}
neighbor = neighbor->next;
}
}
printf("No path found to Charger.\n");
free(q);
}
// 深度优先搜索
void dfs(Graph* g, int start_idx) {
bool visited[MAX_NODES] = {false};
int parent[MAX_NODES];
Stack* s = create_stack();
for (int i = 0; i < g->num_vertices; i++) parent[i] = -1;
push(s, start_idx);
if (debug_mode) printf("DFS started from %s\n", g->vertex_names[start_idx]);
while (!is_empty_stack(s)) {
int current_idx = pop(s);
if (visited[current_idx]) continue;
visited[current_idx] = true;
char* current_name = g->vertex_names[current_idx];
if (debug_mode) printf("Exploring: %s\n", current_name);
// 目标检查
if (strcmp(current_name, "Charger") == 0) {
printf("Goal found!\n");
print_path(parent, NULL, current_idx, g);
free(s);
return;
}
// 将未访问的邻居压入栈(逆序保证顺序)
Node* temp = g->vertices[current_idx];
Node* neighbors[MAX_NODES];
int count = 0;
while (temp != NULL) {
int idx = find_index(g, temp->name);
if (!visited[idx]) {
neighbors[count++] = temp;
}
temp = temp->next;
}
// 逆序入栈以保持字母顺序探索(可选)
for (int i = count - 1; i >= 0; i--) {
int idx = find_index(g, neighbors[i]->name);
if (!visited[idx]) {
parent[idx] = current_idx;
push(s, idx);
if (debug_mode) printf("Pushed: %s (from %s)\n", neighbors[i]->name, current_name);
}
}
}
printf("No path found to Charger.\n");
free(s);
}
// 构建建筑地图
Graph* build_map() {
Graph* g = create_graph();
// 各楼层房间定义
const char* floors[] = {"1", "2", "3"};
const char* prefixes[] = {"A", "B", "C", "D", "E", "F", "G", "H", "K", "L", "M", "N"};
// 添加所有接待室、办公室、门厅、电梯
for (int f = 0; f < 3; f++) {
char floor[2]; sprintf(floor, "%s", floors[f]);
// Lobby and Lift
char lobby[10], lift[10];
sprintf(lobby, "Lobby_%s", floor);
sprintf(lift, "Lift_%s", floor);
add_vertex(g, lobby);
add_vertex(g, lift);
for (int p = 0; p < 4; p++) {
char rec[10], off[10];
sprintf(rec, "%s%s.1", prefixes[p], floor);
sprintf(off, "%s%s.2", prefixes[p], floor);
add_vertex(g, rec);
add_vertex(g, off);
}
}
// 充电站
add_vertex(g, "Charger");
// 连接规则
// 1. 接待室 -> 办公室
for (int f = 0; f < 3; f++) {
char floor[2]; sprintf(floor, "%s", floors[f]);
for (int p = 0; p < 4; p++) {
char rec[10], off[10];
sprintf(rec, "%s%s.1", prefixes[p], floor);
sprintf(off, "%s%s.2", prefixes[p], floor);
add_edge(g, rec, off);
}
}
// 2. 每层接待室 -> 门厅
for (int f = 0; f < 3; f++) {
char floor[2]; sprintf(floor, "%s", floors[f]);
char lobby[10]; sprintf(lobby, "Lobby_%s", floor);
for (int p = 0; p < 4; p++) {
char rec[10];
sprintf(rec, "%s%s.1", prefixes[p], floor);
add_edge(g, rec, lobby);
}
}
// 3. 门厅 -> 电梯(同层)
for (int f = 0; f < 3; f++) {
char floor[2]; sprintf(floor, "%s", floors[f]);
char lobby[10], lift[10];
sprintf(lobby, "Lobby_%s", floor);
sprintf(lift, "Lift_%s", floor);
add_edge(g, lobby, lift);
}
// 4. 电梯上下连接(仅一层差)
add_edge(g, "Lift_1", "Lift_2");
add_edge(g, "Lift_2", "Lift_3");
// 5. 地面电梯 → 充电站
add_edge(g, "Lift_1", "Charger");
return g;
}
// 主函数
int main() {
Graph* g = build_map();
char start_location[NAME_LEN];
int choice;
printf("=== HOOVI Navigation System ===\n");
// 是否启用调试模式
printf("Enable debug mode? (1=yes, 0=no): ");
scanf("%d", &choice);
debug_mode = (choice == 1);
// 输入起点
printf("Enter starting location (e.g., B3.2, Lift_1, N1.1): ");
scanf("%s", start_location);
// 验证输入是否存在
int start_idx = find_index(g, start_location);
if (start_idx == -1) {
printf("Error: Invalid starting location '%s'. Please check spelling.\n", start_location);
return 1;
}
// 选择算法
printf("Choose search method:\n1. BFS (Shortest Path)\n2. DFS\n> ");
scanf("%d", &choice);
printf("Start Location: %s\n", start_location);
printf("Goal Location: Charger\n");
switch (choice) {
case 1:
bfs(g, start_idx);
break;
case 2:
dfs(g, start_idx);
break;
default:
printf("Invalid choice. Using BFS by default.\n");
bfs(g, start_idx);
}
return 0;
}
最新发布