数据结构-实验三
图的操作与实现
利用图的邻接表和邻接矩阵存储结构设计并实现各种操作算法(任选一种存储结构 来实现算法)。
1、图的邻接表和邻接矩阵存储
建立下图的邻接表和邻接矩阵,并输出之。
1 2 3 4 5 6 7 8 9 10
| graph LR 0 ---|28| 1 1 ---|16| 2 2 ---|12| 3 3 ---|22| 4 4 ---|25| 5 5 ---|10| 0 1 ---|14| 6 3 ---|18| 6 4 ---|24| 6
|
1.邻接矩阵
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| #include<iostream> using namespace std;
#define max_vexs 100 #define max_number 9999
typedef struct Graph { char vexs[max_vexs]; int arcs[max_vexs][max_vexs]; int vexsnumber; int arcsnumber; };
Graph* InitGraph(int vexs, int arcs) { Graph* G = new Graph; G->vexsnumber = vexs; G->arcsnumber = arcs; for (int i = 0;i < vexs;i++) { for (int j = 0;j < vexs;j++) { G->arcs[i][j] = max_number; } } return G; } Graph* CreateGraph() { int vexs, arcs; cout << "请输入图的顶点个数以及边的个数:" << endl; cin >> vexs >> arcs; Graph* G = InitGraph(vexs, arcs); cout << "请依次输入顶点的信息:" << endl; for (int i = 0;i < G->vexsnumber;i++) { cin >> G->vexs[i]; } cout << "请输入这个矩阵:" << endl; for (int i = 0;i < G->vexsnumber;i++) { for (int j = 0;j < G->vexsnumber;j++) { cin >> G->arcs[i][j]; } } return G; } void printGraph(Graph* app) { cout << "邻接矩阵表示的图:" << endl; cout << endl; for (int i = 0; i < app->vexsnumber; i++) { for (int j = 0; j < app->vexsnumber; j++) { if (app->arcs[i][j] == max_number) { cout << " ∞ "; } else { cout << app->arcs[i][j] << " "; } } cout << endl; } } int main() { Graph* APP = CreateGraph(); printGraph(APP); return 0; }
|
参考数据:
1 2 3 4 5 6 7 8 9
| 7 9 0 1 2 3 4 5 6 0 28 9999 9999 9999 10 9999 28 0 16 9999 9999 9999 14 9999 16 0 12 9999 9999 18 9999 9999 12 0 22 9999 18 9999 9999 9999 22 0 25 24 10 9999 9999 9999 25 0 9999 9999 14 18 18 24 9999 0
|
参考结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| 请输入图的顶点个数以及边的个数: 7 9 请依次输入顶点的信息: 0 1 2 3 4 5 6 请输入这个矩阵: 0 28 9999 9999 9999 10 9999 28 0 16 9999 9999 9999 14 9999 16 0 12 9999 9999 18 9999 9999 12 0 22 9999 18 9999 9999 9999 22 0 25 24 10 9999 9999 9999 25 0 9999 9999 14 18 18 24 9999 0 邻接矩阵表示的图: 0 28 ∞ ∞ ∞ 10 ∞ 28 0 16 ∞ ∞ ∞ 14 ∞ 16 0 12 ∞ ∞ 18 ∞ ∞ 12 0 22 ∞ 18 ∞ ∞ ∞ 22 0 25 24 10 ∞ ∞ ∞ 25 0 ∞ ∞ 14 18 18 24 ∞ 0
|
2邻接表
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| #include<iostream> using namespace std;
#define max_vexs 100 #define max_number 9999
typedef struct ArcNode { int adjvexs; int weight; struct ArcNode* next; };
typedef struct VexsNode { char data; ArcNode* next; };
typedef struct Grapth { VexsNode vexs[max_vexs]; int vexsnumber; int arcsnumber; }; int LocateVex(Grapth G, char app) { for (int i = 0;i < G.vexsnumber;i++) { if (G.vexs[i].data == app) { return i; } } return -1; } void CreateGrapth(Grapth& app) { cout << "请输入图的顶点个数以及边的个数:" << endl; cin >> app.vexsnumber >> app.arcsnumber; cout << "请依次输入顶点的信息:" << endl; for (int i = 0;i < app.vexsnumber;i++) { cin >> app.vexs[i].data; app.vexs[i].next = NULL; } cout << "请依次输入边的信息(起点 权重 终点):" << endl; for (int b = 0;b < app.arcsnumber;b++) { char v1, v2;int weight; cin >> v1 >> weight >> v2; int c = LocateVex(app, v1); int s = LocateVex(app, v2);
ArcNode* p1 = new ArcNode; p1->weight = weight; p1->adjvexs = s; p1->next = app.vexs[c].next; app.vexs[c].next = p1;
ArcNode* p2 = new ArcNode; p2->weight = weight; p2->adjvexs = c; p2->next = app.vexs[s].next; app.vexs[s].next = p2; } }
void PrintGraph(Grapth& app) { cout << "图的邻接表表示如下:" << endl; for (int i = 0; i < app.vexsnumber; i++) { cout << app.vexs[i].data; ArcNode* temp = app.vexs[i].next; while (temp) { cout << " -> (" << app.vexs[temp->adjvexs].data << ", " << temp->weight << ")"; temp = temp->next; } cout << endl; } } int main() { Grapth app; CreateGrapth(app); PrintGraph(app); return 0; }
|
参考数据:
1 2 3 4 5 6 7 8 9 10 11
| 7 9 0 1 2 3 4 5 6 0 28 1 0 10 5 1 16 2 1 14 6 2 12 3 2 18 6 3 22 6 4 25 5 4 24 6
|
参考结果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 请输入图的顶点个数以及边的个数: 7 9 请依次输入顶点的信息: 0 1 2 3 4 5 6 请依次输入边的信息(起点 权重 终点): 0 28 1 0 10 5 1 16 2 1 14 6 2 12 3 2 18 6 3 22 6 4 25 5 4 24 6 图的邻接表表示如下: 0 -> (5, 10) -> (1, 28) 1 -> (6, 14) -> (2, 16) -> (0, 28) 2 -> (6, 18) -> (3, 12) -> (1, 16) 3 -> (6, 22) -> (2, 12) 4 -> (6, 24) -> (5, 25) 5 -> (4, 25) -> (0, 10) 6 -> (4, 24) -> (3, 22) -> (2, 18) -> (1, 14)
|
2、图的各种遍历算法实现
以任意结点v为起点,实现上述图的深度优先和广度优先遍历算法
深度优先
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57
| #include<iostream> using namespace std;
#define max_vexs 100 #define max_number 9999
typedef struct Graph { char vexs[max_vexs]; int arcs[max_vexs][max_vexs]; int vexsnumber; int arcsnumber; };
Graph* InitGraph(int vexs, int arcs) { Graph* G = new Graph; G->vexsnumber = vexs; G->arcsnumber = arcs; for (int i = 0;i < vexs;i++) { for (int j = 0;j < vexs;j++) { G->arcs[i][j] = max_number; } } return G; } Graph* CreateGraph() { int vexs, arcs; cout << "请输入图的顶点个数以及边的个数:" << endl; cin >> vexs >> arcs; Graph* G = InitGraph(vexs, arcs); cout << "请依次输入顶点的信息:" << endl; for (int i = 0;i < G->vexsnumber;i++) { cin >> G->vexs[i]; } cout << "请输入这个矩阵:" << endl; for (int i = 0;i < G->vexsnumber;i++) { for (int j = 0;j < G->vexsnumber;j++) { cin >> G->arcs[i][j]; } } return G; } void DFS(Graph* app,int arr[], int index) { cout << app->vexs[index] << " "; arr[index] = 1; for (int i = 0;i < app->vexsnumber;i++) { if (app->arcs[index][i] != max_number && !arr[i]) { DFS(app, arr, i); } } } int main() { Graph* APP = CreateGraph(); int visted[max_vexs] = { 0 }; DFS(APP, visted, 0); delete APP; return 0; }
|
广度优先
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104
| #include<iostream> using namespace std;
#define max_vexs 100 #define max_number 9999
typedef struct Graph { char vexs[max_vexs]; int arcs[max_vexs][max_vexs]; int vexsnumber; int arcsnumber; }; struct node { int data; struct node* next; }; class queue { private: node* root; public: queue() { root = new node; root->next = NULL; } void pushqueue(int data) { node* node1 = root; while (node1->next) { node1 = node1->next; } node* node2 = new node; node2->data = data; node2->next = nullptr; node1->next = node2; } int popqueue() { if (root->next == NULL) return NULL; node* node1 = root->next; int number = node1->data; root->next = node1->next; free(node1); return number; } bool empty() { return root->next == NULL; } ~queue() { while (root) { node* temp = root; root = root->next; delete temp; } } };
Graph* InitGraph(int vexs, int arcs) { Graph* G = new Graph; G->vexsnumber = vexs; G->arcsnumber = arcs; for (int i = 0;i < vexs;i++) { for (int j = 0;j < vexs;j++) { G->arcs[i][j] = max_number; } } return G; } Graph* CreateGraph() { int vexs, arcs; cout << "请输入图的顶点个数以及边的个数:" << endl; cin >> vexs >> arcs; Graph* G = InitGraph(vexs, arcs); cout << "请依次输入顶点的信息:" << endl; for (int i = 0;i < G->vexsnumber;i++) { cin >> G->vexs[i]; } cout << "请输入这个矩阵:" << endl; for (int i = 0;i < G->vexsnumber;i++) { for (int j = 0;j < G->vexsnumber;j++) { cin >> G->arcs[i][j]; } } return G; } void BFS(Graph* app, bool visted[], int index) { queue newqueue; visted[index] = true; cout << app->vexs[index] << " "; newqueue.pushqueue(index); while (!newqueue.empty()) { int indexnumber = newqueue.popqueue(); for (int i = 0;i < app->vexsnumber;i++) { if (!visted[i] && app->arcs[indexnumber][i] != max_number) { cout << app->vexs[i] << " "; visted[i] = true; newqueue.pushqueue(i); } } } } int main() { Graph* APP = CreateGraph(); bool visted[max_vexs] = { false }; BFS(APP, visted, 0); return 0; }
|
3、最小生成树的算法实现
利用普里姆(Prim)算法和克鲁斯卡尔(Kruskal)算法求上图的最小生成树,算法实现 代码必须有注释。
普里姆(Prim)算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
| #include<iostream> using namespace std;
#define max_vexs 100 #define max_number 9999
typedef struct Graph { char vexs[max_vexs]; int arcs[max_vexs][max_vexs]; int vexsnumber; int arcsnumber; }; typedef struct CloseEdge { char vexs; int weight; };
Graph* InitGraph(int vexs, int arcs) { Graph* G = new Graph; G->vexsnumber = vexs; G->arcsnumber = arcs; for (int i = 0;i < vexs;i++) { for (int j = 0;j < vexs;j++) { G->arcs[i][j] = max_number; } } return G; } Graph* CreateGraph() { int vexs, arcs; cout << "请输入图的顶点个数以及边的个数:" << endl; cin >> vexs >> arcs; Graph* G = InitGraph(vexs, arcs); cout << "请依次输入顶点的信息:" << endl; for (int i = 0;i < G->vexsnumber;i++) { cin >> G->vexs[i]; } cout << "请输入这个矩阵:" << endl; for (int i = 0;i < G->vexsnumber;i++) { for (int j = 0;j < G->vexsnumber;j++) { cin >> G->arcs[i][j]; } } return G; } CloseEdge* InitCloseEdge(Graph* app, int indexnumber) { CloseEdge* closeedge = new CloseEdge[app->vexsnumber]; for (int i = 0;i < app->vexsnumber;i++) { closeedge[i].vexs = app->vexs[indexnumber]; closeedge[i].weight = app->arcs[indexnumber][i]; } return closeedge; } int GetMinEdge(Graph* app, CloseEdge* closeedge) { int indexnumber = -1; int minnumber = max_number; for (int i = 0;i < app->vexsnumber;i++) { if (closeedge[i].weight != 0 && closeedge[i].weight < minnumber) { minnumber = closeedge[i].weight; indexnumber = i; } } return indexnumber; } void Prim(Graph* app,int indexnumber) { int minnumber; CloseEdge* closeedge = InitCloseEdge(app, indexnumber); cout << "Prim最小生成树为:" << endl; for (int i = 0;i < app->vexsnumber - 1;i++) { minnumber = GetMinEdge(app, closeedge); if (minnumber == -1) { cout << "无法找到最小权值的边,可能图不连通。" << endl; break; } cout << closeedge[minnumber].vexs << "--->" << app->vexs[minnumber] << " " << closeedge[minnumber].weight << endl; closeedge[minnumber].weight = 0; for (int j = 0;j < app->vexsnumber;j++) { if (app->arcs[minnumber][j] < closeedge[j].weight) { closeedge[j].weight = app->arcs[minnumber][j]; closeedge[j].vexs = app->vexs[minnumber]; } } } } int main() { Graph* APP = CreateGraph(); int visted[max_vexs] = { 0 }; Prim(APP, 0); delete APP; return 0; }
|
克鲁斯卡尔(Kruskal)算法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
| #include<iostream> using namespace std;
#define max_vexs 100 #define max_number 9999
typedef struct Graph { char vexs[max_vexs]; int arcs[max_vexs][max_vexs]; int vexsnumber; int arcsnumber; }; typedef struct Edge { int start; int end; int weight; }; Edge* InitEdge(Graph* app) { int index = 0; Edge* edge = new Edge[app->arcsnumber]; for (int i = 0; i < app->vexsnumber; i++) { for (int j = i + 1; j < app->vexsnumber; j++) { if (app->arcs[i][j] != max_number) { edge[index].start = i; edge[index].end = j; edge[index].weight = app->arcs[i][j]; index++; } } } return edge; }
Graph* InitGraph(int vexs, int arcs) { Graph* G = new Graph(); G->vexsnumber = vexs; G->arcsnumber = arcs; for (int i = 0;i < vexs;i++) { for (int j = 0;j < vexs;j++) { G->arcs[i][j] = max_number; } } return G; } Graph* CreateGraph() { int vexs, arcs; cout << "请输入图的顶点个数以及边的个数:" << endl; cin >> vexs >> arcs; Graph* G = InitGraph(vexs, arcs); cout << "请依次输入顶点的信息:" << endl; for (int i = 0;i < G->vexsnumber;i++) { cin >> G->vexs[i]; } cout << "请输入这个矩阵:" << endl; for (int i = 0;i < G->vexsnumber;i++) { for (int j = 0;j < G->vexsnumber;j++) { cin >> G->arcs[i][j]; } } return G; } void sortEdge(Edge* edge, Graph* G) { Edge temp; for (int i = 0; i < G->arcsnumber - 1; i++) { for (int j = 0; j < G->arcsnumber - i - 1; j++) { if (edge[j].weight > edge[j + 1].weight) { temp = edge[j]; edge[j] = edge[j + 1]; edge[j + 1] = temp; } } } } void kruskal(Graph* G) { int connected[max_number]; for (int i = 0; i < G->vexsnumber; i++) { connected[i] = i; } Edge* edge = InitEdge(G); sortEdge(edge, G); for (int i = 0; i < G->arcsnumber; i++) { int start = connected[edge[i].start]; int end = connected[edge[i].end]; if (start != end) { cout << G->vexs[edge[i].start] << "--->" << G->vexs[edge[i].end] << "-----" << edge[i].weight << endl; for (int j = 0; j < G->vexsnumber; j++) { if (connected[j] == end) { connected[j] = start; } } } } } int main() { Graph* APP = CreateGraph(); kruskal(APP); delete APP; return 0; }
|
4、最短路径的算法实现
(1) 利用狄克斯特拉(Dijkstra)算法求上图中任意结点 v 到其它结点 w 的最短路径, 算法实现代码必须有注释;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| #include<iostream> using namespace std;
#define max_vexs 100 #define max_number 9999
bool visted[max_number]; int path[max_number]; int power[max_number];
typedef struct Graph { char vexs[max_vexs]; int arcs[max_vexs][max_vexs]; int vexsnumber; int arcsnumber; };
Graph* InitGraph(int vexs, int arcs) { Graph* G = new Graph; G->vexsnumber = vexs; G->arcsnumber = arcs; for (int i = 0;i < vexs;i++) { for (int j = 0;j < vexs;j++) { G->arcs[i][j] = max_number; } } return G; } Graph* CreateGraph() { int vexs, arcs; cout << "请输入图的顶点个数以及边的个数:" << endl; cin >> vexs >> arcs; Graph* G = InitGraph(vexs, arcs); cout << "请依次输入顶点的信息:" << endl; for (int i = 0;i < G->vexsnumber;i++) { cin >> G->vexs[i]; } cout << "请输入这个矩阵:" << endl; for (int i = 0;i < G->vexsnumber;i++) { for (int j = 0;j < G->vexsnumber;j++) { cin >> G->arcs[i][j]; } } return G; } void Dijkstra(Graph* G, int index) { for (int i = 0;i < G->vexsnumber;i++) { visted[i] = false; power[i] = G->arcs[index][i]; if (power[i] < max_number) { path[i] = index; } else { path[i] = -1; } } visted[index] = true; power[index] = 0; for (int k = 1;k < G->vexsnumber;k++) { int minnumber = max_number; int vexs; for (int i = 0;i < G->vexsnumber;i++) { if (!visted[i] && power[i] < minnumber) { minnumber = power[i]; vexs = i; } } visted[vexs] = true; for (int j = 0;j < G->vexsnumber;j++) { if (!visted[j] && (power[vexs] + G->arcs[vexs][j] < power[j])) { power[j] = power[vexs] + G->arcs[vexs][j]; path[j] = vexs; } } } for (int d = 0;d < G->vexsnumber;d++) { cout << G->vexs[d] << " " << "path[" << path[d] << "]" << " " << "power:" << power[d] << endl; } } int main() { Graph* APP = CreateGraph(); Dijkstra(APP, 0); delete APP; return 0; }
|
(2) 利用弗洛伊德(Floyd)算法求上图中的多源最短路径,算法实现代码必须有注释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| #include<iostream> using namespace std;
#define max_vexs 100 #define max_number 9999
int D[max_vexs][max_vexs]; int Path[max_vexs][max_vexs];
typedef struct Graph { char vexs[max_vexs]; int arcs[max_vexs][max_vexs]; int vexsnumber; int arcsnumber; };
Graph* InitGraph(int vexs, int arcs) { Graph* G = new Graph; G->vexsnumber = vexs; G->arcsnumber = arcs; for (int i = 0;i < vexs;i++) { for (int j = 0;j < vexs;j++) { G->arcs[i][j] = max_number; } } return G; } Graph* CreateGraph() { int vexs, arcs; cout << "请输入图的顶点个数以及边的个数:" << endl; cin >> vexs >> arcs; Graph* G = InitGraph(vexs, arcs); cout << "请依次输入顶点的信息:" << endl; for (int i = 0;i < G->vexsnumber;i++) { cin >> G->vexs[i]; } cout << "请输入这个矩阵:" << endl; for (int i = 0;i < G->vexsnumber;i++) { for (int j = 0;j < G->vexsnumber;j++) { cin >> G->arcs[i][j]; } } return G; } void Floyd(Graph* app) { for (int i = 0;i < app->vexsnumber;i++) { for (int j = 0;j < app->vexsnumber;j++) { D[i][j] = app->arcs[i][j]; if (app->arcs[i][j] < max_number) { Path[i][j] = i; } } } for (int k = 0;k < app->vexsnumber;k++) { for (int g = 0;g < app->vexsnumber;g++) { for (int t = 0;t < app->vexsnumber;t++) { if (D[g][k] + D[k][t] < D[g][t]) { D[g][t] = D[g][k] + D[k][t]; Path[g][t] = Path[k][t]; } } } } cout << "权值大小:" << endl; for (int s = 0;s < app->vexsnumber;s++) { for (int e = 0;e < app->vexsnumber;e++) { cout << D[s][e] << " "; } cout << endl; } cout << "前驱大小:" << endl; for (int s = 0;s < app->vexsnumber;s++) { for (int e = 0;e < app->vexsnumber;e++) { cout << Path[s][e] << " "; } cout << endl; } } int main() { Graph* APP = CreateGraph(); Floyd(APP); delete APP; return 0; }
|
5、求解无权图的单源最短路径问题(结合迷宫的最短路径问题)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
| #include <iostream> #include <stdio.h> #include <stdlib.h> using namespace std;
#define max_size 10
int px[4] = { 0, 0, -1, 1 }; int py[4] = { 1, -1, 0, 0 };
struct postion { int x, y; int ans = 0; }; struct path { int x, y; }; path pre[max_size][max_size]; struct map { int m, n; int app[max_size][max_size]; bool visited[max_size][max_size] = { false }; int x1, y1; int x2, y2; }; struct node { postion data; struct node* next; }; class queue { private: node* root; public: queue() { root = new node; root->next = NULL; } void push(postion data) { node* node1 = root; while (node1->next) { node1 = node1->next; } node* node2 = new node; node2->data = data; node2->next = nullptr; node1->next = node2; } postion front() { if (root->next == NULL) { return { -1,-1 }; } else { postion number = root->next->data; return number; } }; bool empty() { return root->next == NULL; } void pop() { if (root->next == NULL) return; node* node1 = root->next; root->next = node1->next; free(node1); } void printnode() { node* node1 = root->next; printf("队列:"); while (node1) { printf("-->(%d,%d)", node1->data.x, node1->data.y); node1 = node1->next; } printf("\n"); } ~queue() { while (root) { node* temp = root; root = root->next; delete temp; } } }; void bfs(map& site) { postion currentsite; postion nextsite; currentsite.x = site.x1; currentsite.y = site.y1; currentsite.ans = 0; site.visited[currentsite.x][currentsite.y] = true; queue app; app.push(currentsite); while (!app.empty()) { currentsite = app.front(); app.pop(); if (currentsite.x == site.x2 && currentsite.y == site.y2) { cout << "走出了迷宫!" << endl; cout << "共走了: " << currentsite.ans << " 步" << endl; path truepath[max_size * max_size]; cout << "走过的路径为:"; truepath[0].x = site.x2; truepath[0].y = site.y2; int number = 1; bool istrue = true; truepath[number] = pre[site.x2][site.y2]; while (istrue) { if (truepath[number].x == site.x1 && truepath[number].y == site.y1) { istrue = false; break; } else { number++; truepath[number] = pre[truepath[number - 1].x][truepath[number - 1].y]; } } cout << "这个的走过的路径为:"; for (int i = currentsite.ans;i >= 0;i--) { cout << "(" << truepath[i].x << "," << truepath[i].y << ")" << "-->"; } cout << "endl" << endl; return; } for (int i = 0; i < 4; i++) { nextsite.x = currentsite.x + px[i]; nextsite.y = currentsite.y + py[i]; if (nextsite.x >= 1 && nextsite.y >= 1 && !site.visited[nextsite.x][nextsite.y] && site.app[nextsite.x][nextsite.y] && nextsite.x <= site.m && nextsite.y <= site.n) { pre[nextsite.x][nextsite.y].x = currentsite.x; pre[nextsite.x][nextsite.y].y = currentsite.y; nextsite.ans = currentsite.ans + 1; site.visited[nextsite.x][nextsite.y] = true; app.push(nextsite); } } } cout << "没有走出迷宫" << endl; } int main() { cout << "请输入这个迷宫的长和宽 m 与 n:" << endl; map total; scanf_s("%d", &total.m); scanf_s("%d", &total.n); cout << "请输入这个迷宫的值,1代表可以通过的,0代表不可以通过的:" << endl; for (int i = 1; i <= total.m; i++) { for (int j = 1; j <= total.n; j++) { scanf_s("%d", &total.app[i][j]); } } cout << "请输入起点的值 (x1, y1): "; cin >> total.x1 >> total.y1; cout << "请输入终点的值 (x2, y2): "; cin >> total.x2 >> total.y2; if (total.x1 < 1 || total.x1 > total.m || total.y1 < 1 || total.y1 > total.n || total.app[total.x1][total.y1] == 0) { cout << "起点不合法!" << endl; return 0; } if (total.x2 < 1 || total.x2 > total.m || total.y2 < 1 || total.y2 > total.n || total.app[total.x2][total.y2] == 0) { cout << "终点不合法!" << endl; return 0; } bfs(total); return 0; }
|
参考数据:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 10 10 1 1 1 1 1 0 1 1 1 1 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 0 0 0 0 1 1 1 1 1 1 1 10 10
|
参考结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 请输入这个迷宫的长和宽 m 与 n: 10 10 请输入这个迷宫的值,1代表可以通过的,0代表不可以通过的: 1 1 1 1 1 0 1 1 1 1 0 0 0 1 0 0 0 0 1 1 1 1 1 1 1 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 1 0 1 1 1 1 1 1 1 0 1 1 1 0 0 0 0 0 1 1 1 1 1 请输入起点的值 (x1, y1): 1 1 请输入终点的值 (x2, y2): 10 10 走出了迷宫! 共走了: 18 步 走过的路径为:这个的走过的路径为:(1,1)-->(1,2)-->(1,3)-->(1,4)-->(2,4)-->(3,4)-->(3,5)-->(3,6)-->(3,7)-->(4,7)-->(5,7)-->(5,8)-->(5,9)-->(5,10)-->(6,10)-->(7,10)-->(8,10)-->(9,10)-->(10,10)-->endl
|
参考数据:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| 15 15 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 0 1 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 15 15
|
参考结果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| 请输入这个迷宫的长和宽 m 与 n: 15 15 请输入这个迷宫的值,1代表可以通过的,0代表不可以通过的: 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 1 1 0 1 0 0 0 0 0 0 0 0 0 1 0 1 1 0 1 0 1 1 1 1 1 1 1 0 1 0 1 1 0 1 0 1 0 0 0 0 0 1 0 1 0 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1 0 1 0 1 0 1 1 1 0 1 0 1 0 1 1 0 1 0 0 0 0 0 0 0 1 0 1 0 1 1 0 1 1 1 1 1 1 1 1 1 0 1 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 请输入起点的值 (x1, y1): 1 1 请输入终点的值 (x2, y2): 15 15 走出了迷宫! 共走了: 28 步 走过的路径为:这个的走过的路径为:(1,1)-->(1,2)-->(1,3)-->(1,4)-->(1,5)-->(1,6)-->(1,7)-->(1,8)-->(1,9)-->(1,10)-->(1,11)-->(1,12)-->(1,13)-->(1,14)-->(1,15)-->(2,15)-->(3,15)-->(4,15)-->(5,15)-->(6,15)-->(7,15)-->(8,15)-->(9,15)-->(10,15)-->(11,15)-->(12,15)-->(13,15)-->(14,15)-->(15,15)-->endl
|
参考不通过数据:
1 2 3 4 5 6 7 8 9 10
| 7 7 1 1 1 1 0 0 0 1 0 0 1 0 1 1 1 0 1 1 1 1 0 1 0 0 0 0 1 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 7 7
|
参考结果:
1 2 3 4 5 6 7 8 9 10 11 12 13
| 请输入这个迷宫的长和宽 m 与 n: 7 7 请输入这个迷宫的值,1代表可以通过的,0代表不可以通过的: 1 1 1 1 0 0 0 1 0 0 1 0 1 1 1 0 1 1 1 1 0 1 0 0 0 0 1 0 1 1 1 1 0 1 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 请输入起点的值 (x1, y1): 1 1 请输入终点的值 (x2, y2): 7 7 没有走出迷宫
|