赞
踩
根据输入的长和宽随机生成一个迷宫,随机生成或者输入一个起点和一个终点,运用广度优先搜索算法,找到这个迷宫中起点到终点的最短路径,并输出结果。
1.根据给定的迷宫长和宽创建一个动态数组,初始化数组并随机生成一个迷宫,再随机生成或者输入一个起点和一个终点。
2.设置一个结构体Node,其中包括点的坐标,以及五个指针:front(用于后期回溯得出的最短路径)、left、right、up、down。将起点和终点存入Node,从起点开始分别遍历其上下左右四个坐标是否有“墙”,若没有,向所查询的方向前进一步,新建一个Node,存入该点。
3.另设置一个结构体Queue,每前进一步,将新的点的指针存入Queue组成的链表,从头到尾遍历这个链表,链表中每个指针所指向的点都会重复步骤2。
4.重复2、3步骤,遍历整个树,以此实现广度搜索算法,直至找到终点。
5.如果找到了终点,则从已存好的终点Node开始,通过指针front一步步还原这个路径,直至走到起点,然后输出这个过程得到最终的最短路径。如果没有找到,则输出“No path.”。
- #define _CRT_SECURE_NO_WARNINGS
- #include <stdio.h>
- #include <stdlib.h>
- #include <malloc.h>
- #include <Windows.h>
-
- typedef struct Point
- {
- int arrrow;
- int arrcol;
- }Point;
-
- typedef struct Node
- {
- Point point;
- struct Node* front;
- struct Node* left;
- struct Node* right;
- struct Node* up;
- struct Node* down;
- }Node;
-
- typedef struct Queue
- {
- struct Node* node;
- struct Queue* next;
- };
-
- struct Node* CreateNode(int row, int col)//长长的链表捏
- {
- struct Node* node = (struct Node*)malloc(sizeof(struct Node));
- node->point.arrrow = row;
- node->point.arrcol = col;
- node->front = NULL;
- node->left = NULL;
- node->right = NULL;
- node->up = NULL;
- node->down = NULL;
- return node;
- }
-
- struct Queue* CreateQueue(struct Node* addnode)//动态队列记录每层搜索
- {
- struct Queue* queue = (struct Queue*)malloc(sizeof(struct Queue));
- queue->node = addnode;
- queue->next = NULL;
- return queue;
- }
-
- //设置颜色的捏
- VOID SetColor(UINT uFore, UINT uBack)
- {
- HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
- SetConsoleTextAttribute(handle, uFore + uBack * 0x10);
- }
-
- //测试,打印全部迷宫
- void TextPrint(char** maze, int mazerow, int mazecol)
- {
- for (int i = 0; i < mazerow; i++)
- {
- for (int j = 0; j < mazecol; j++)
- {
- printf("%c", maze[i][j]);
- }
- printf("\n");
- }
- printf("\n");
- }
-
- //打印整个迷宫捏
- void PrintMaze(char** maze, int mazerow, int mazecol)
- {
- for (int i = 0; i < mazerow; i++)
- {
- for (int j = 0; j < mazecol; j++)
- {
- if (maze[i][j] == '=')
- printf(" ");
- else if (maze[i][j] == '1')
- printf(" ");
- else if (maze[i][j] == '0')
- printf(" ");
- else if (maze[i][j] == '-')
- printf("---");
- else if (maze[i][j] == ' ')
- printf(" ");
- else if (maze[i][j] == '!')
- {
- SetColor(4, 0);
- printf(" ! ");
- SetColor(7, 0);
- }
- else if (maze[i][j] == '<' || maze[i][j] == '>')
- {
- SetColor(4, 0);
- printf("%c", maze[i][j]);
- SetColor(7, 0);
- }
- else if (maze[i][j] == '*')
- {
- SetColor(4, 0);
- printf(" * ");
- SetColor(7, 0);
- }
- else
- printf("%c", maze[i][j]);
- }
- printf("\n");
- }
- printf("\n");
- }
-
- //初始化迷宫
- void InitMaze(char **maze, int mazerow, int mazecol)
- {
- //初始
- for (int i = 0; i < mazerow; i++)
- {
- for (int j = 0; j < mazecol; j++)
- {
- maze[i][j] = ' ';
- }
- }
-
- //拐角
- for (int i = 0; i < mazerow; i += 2)
- {
- for (int j = 0; j < mazecol; j += 2)
- {
- maze[i][j] = '+';
- }
- }
-
- //左右墙壁
- for (int i = 1; i < mazerow; i += 2)
- {
- maze[i][0] = '|';
- maze[i][mazecol - 1] = '|';
- }
-
- //上下墙壁
- for (int i = 1; i < mazecol; i += 2)
- {
- maze[0][i] = '-';
- maze[mazerow - 1][i] = '-';
- }
-
- }
-
- //随机生成迷宫
- void CreateMaze(char **maze, int mazerow, int mazecol, int wallweight)
- {
- srand((unsigned)time(NULL));
- for (int i = 1; i < mazerow; i += 2)
- {
- for (int j = 2; j < mazecol - 2; j += 2)
- {
- int randnum = rand() % 10 + 1;
- if (randnum <= wallweight)
- {
- maze[i][j] = '|';
- }
- else
- maze[i][j] = '=';//原本所有通路都是1,为了打印时的美观性,将上下与左右区分
- }
- }
- for (int i = 1; i < mazecol; i += 2)
- {
- for (int j = 2; j < mazerow - 2; j += 2)
- {
- int randnum = rand() % 10 + 1;
- if (randnum <= wallweight)
- {
- maze[j][i] = '-';
- }
- else
- maze[j][i] = '1';
- }
- }
- PrintMaze(maze, mazerow, mazecol);
- }
-
- //设置起点和终点
- Point StartAndEnd(char** maze, int row, int col)
- {
- /*srand((unsigned)time(NULL)); */
- Point point;
- int randomrow = rand() % row + 1;
- int randomcol = rand() % col + 1;
- printf("[%d, %d]\n", randomrow, randomcol);
- point.arrrow = randomrow * 2 - 1;
- point.arrcol = randomcol * 2 - 1;
- return point;
- }
-
- //广度优先算法
- int BFS(char** maze, Point start, Point end, int mazerow, int mazecol)
- {
- int row = start.arrrow;
- int col = start.arrcol;
- struct Node* startnode = CreateNode(row, col);//startnode不能动
- row = end.arrrow;
- col = end.arrcol;
- struct Node* endnode = CreateNode(row, col);
- struct Node* tmpnode = startnode;
- struct Queue* headqueue = CreateQueue(startnode);
- struct Queue* head = headqueue;//便于释放内存
- struct Queue* tmpqueue = headqueue;
- int flag = 0;
-
- //广度搜索遍历
- while (1)
- {
- row = headqueue->node->point.arrrow;
- col = headqueue->node->point.arrcol;
- tmpnode = headqueue->node;
- maze[row][col] = '0';
- if (maze[row][col - 1] == '=' && maze[row][col - 2] != '0')
- {
- struct Node* node = CreateNode(row, col - 2);
- node->front = tmpnode;
- tmpnode->left = node;
- maze[row][col - 2] = '0';
- if (row == end.arrrow && col - 2 == end.arrcol)
- {
- flag = 1;
- endnode = node;
- printf("found\n");
- break;
- }
- struct Queue* queue = CreateQueue(node);
- tmpqueue->next = queue;
- tmpqueue = queue;
- }
- if (maze[row][col + 1] == '=' && maze[row][col + 2] != '0')
- {
- struct Node* node = CreateNode(row, col + 2);
- node->front = tmpnode;
- tmpnode->right= node;
- maze[row][col + 2] = '0';
- if (row == end.arrrow && col + 2 == end.arrcol)
- {
- flag = 1;
- endnode = node;
- printf("found\n");
- break;
- }
- struct Queue* queue = CreateQueue(node);
- tmpqueue->next = queue;
- tmpqueue = queue;
- }
- if (maze[row - 1][col] == '1' && maze[row - 2][col] != '0')
- {
- struct Node* node = CreateNode(row - 2, col);
- node->front = tmpnode;
- tmpnode->up = node;
- maze[row - 2][col] = '0';
- if (row - 2 == end.arrrow && col == end.arrcol)
- {
- flag = 1;
- endnode = node;
- printf("found\n");
- break;
- }
- struct Queue* queue = CreateQueue(node);
- tmpqueue->next = queue;
- tmpqueue = queue;
- }
- if (maze[row + 1][col] == '1' && maze[row + 2][col] != '0')
- {
- struct Node* node = CreateNode(row + 2, col);
- node->front = tmpnode;
- tmpnode->down = node;
- maze[row + 2][col] = '0';
- if (row + 2 == end.arrrow && col == end.arrcol)
- {
- flag = 1;
- endnode = node;
- printf("found\n");
- break;
- }
- struct Queue* queue = CreateQueue(node);
- tmpqueue->next = queue;
- tmpqueue = queue;
- }
- if (headqueue->next == NULL)
- {
- flag = 0;
- printf("No path...\n");
- break;
- }
- headqueue = headqueue->next;
- }
-
- //如果找到,回溯路线
- if (flag)
- {
- //测试
- TextPrint(maze, mazerow, mazecol);
-
- flag = 0;
-
- tmpnode = endnode;
- while (1)
- {
- row = tmpnode->point.arrrow;
- col = tmpnode->point.arrcol;
- maze[row][col] = '*';
- tmpnode = tmpnode->front;
- if (tmpnode == NULL)
- break;
- if (tmpnode->left == endnode)
- {
- maze[row][col + 1] = '<';
- }
- else if (tmpnode->right == endnode)
- {
- maze[row][col - 1] = '>';
- }
- else if (tmpnode->up == endnode)
- {
- maze[row + 1][col] = '!';
- }
- else if (tmpnode->down == endnode)
- {
- maze[row - 1][col] = '!';
- }
- endnode = endnode->front;
-
- flag++;
- }
- }
- tmpqueue = head;
- while (tmpqueue != NULL)
- {
- tmpqueue = tmpqueue->next;
- free(head->node);
- free(head);
- head = tmpqueue;
- }
- return flag;
- }
-
- int main()
- {
- //输入行和列
- int row = 0, col = 0;
- printf("please input row(行)and col(列):\n");
- scanf("%d %d", &row, &col);
-
- if (!(row > 0 && col > 0))
- {
- printf("input ERROR\n");
- return 1;
- }
-
- int wallweight = 0;
- printf("please input the weight of wall(1 ~ 10, less than 4 best):\n");
- scanf("%d", &wallweight);
-
- if (!(wallweight > 0 && wallweight <= 10))
- {
- printf("input ERROR\n");
- return 1;
- }
-
- //创建一个动态数组
- int mazerow = row * 2 + 1;
- int mazecol = col * 2 + 1;
- char **maze = (char**)calloc(mazerow, sizeof(char*));
-
- if (maze == NULL)
- {
- printf("malloc ERROR\n");
- return 1;
- }
- for (int i = 0; i < mazerow; i++)
- {
- maze[i] = (char*)calloc(mazecol, sizeof(char));
-
- if (maze[i] == NULL)
- {
- printf("malloc ERROR\n");
- return 1;
- }
- }
-
- //初始化迷宫
- InitMaze(maze, mazerow, mazecol);
-
- //随机生成迷宫
- int x = 0;
- do
- {
- CreateMaze(maze, mazerow, mazecol, wallweight);
- printf("Reset the maze? Yes(1)/No(0)\n");
- scanf("%d", &x);
- } while (x);
-
- //设置起点和终点
- int choice = 0;
- Point start;
- Point end;
- printf("Random point(1) OR Input point(0)\n");
- scanf("%d", &choice);
- if (choice == 1)
- {
- start = StartAndEnd(maze, (int)(row / 2), (int)(col / 2));
- end = StartAndEnd(maze, row, col);
- }
- else if (choice == 0)
- {
- int row = 0;
- int col = 0;
- printf("Please input startpoint row col\n");
- scanf("%d %d", &row, &col);
- start.arrrow = row * 2 - 1;
- start.arrcol = col * 2 - 1;
-
- printf("Please input endpoint row col\n");
- scanf("%d %d", &row, &col);
- end.arrrow = row * 2 - 1;
- end.arrcol = col * 2 - 1;
- }
- else
- {
- printf("Input ERROR\n");
- return -1;
- }
-
- //广度优先算法
- int flag = BFS(maze, start, end, mazerow, mazecol);
-
- //输出结果
- if (flag)
- {
- PrintMaze(maze, mazerow, mazecol);
- printf("step = %d\n", flag);
- }
-
- //释放内存
- for (int i = 0; i < mazerow; i++)
- {
- free(maze[i]);
- }
- free(maze);
-
-
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。