數據結構設計——用隊列實現迷宮問題的求解
1,問題描述
以一個m*n的長方陣表示迷宮,0和1分別表示迷宮中的通路和障礙。迷宮問題要求求出從入口(1,1)到出口(m,n)的一條通路,或得出沒有通路的結論。 基本要求: 首先實現一個以鏈表作存儲結構的棧類型,然後編寫一個求迷宮問題的非遞歸程序,求得的通路,其中:(i,j)指示迷宮中的一個坐標, d表示走到下一坐標的方向。 左上角(1,1)為入口,右下角(m,n)為出口。
2.設計思路:
用隊列實現迷宮問題的求解;
3.實驗代碼:
隊列實現:
********************************************************************************************
1 //maze_queue.cpp 2 #include<stdio.h> 3 #include<stdlib.h> 4 #include<windows.h> 5 #include"seqqueue.h" 6 7 #define MAX_ROW 12 8 #define MAX_COL 14 9 10 int maze[12][14] = { 11 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 0, 1, 1, 1, 13 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 14 1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 1, 0, 0, 1, 15 1, 0, 1, 1, 1, 0, 1, 0, 0, 0, 1, 0, 1, 1, 16 1, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 1, 17 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 1, 18 1, 1, 0, 1, 0, 1, 0, 1, 1, 0, 0, 0, 0, 1, 19 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 1, 20 1, 1, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 21 1, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 22 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 23 }; 24 25 void print_line(void) 26 { 27 int i, j; 28 system("cls"); 29 printf("迷宮如下‘■’代表墻,數字 或者‘☆’表示路徑\n"); 30 for (i = 0; i < MAX_ROW; i++){ 31 for (j = 0; j < MAX_COL; j++) 32 if (maze[i][j] == 1) printf("■"); 33 else if (maze[i][j] >= 3){ 34 printf("%2d", maze[i][j] - 2); 35 /*if (i == MAX_ROW-2 && j == MAX_COL-2) printf("★"); 36 else printf("☆");*/ 37 } 38 else printf(" "); 39 printf("\n"); 40 } 41 printf("已找到出路...\n"); 42 printf("可見,用隊列求解迷宮問題,可以找出一條最短路徑\n"); 43 } 44 45 void visit(int row, int col,PSeqQueue S) 46 { 47 struct point visit_point = { row, col, S->front }; 48 maze[row][col] = 2; 49 In_SeqQueue(S,visit_point); 50 } 51 52 int main() 53 { 54 struct point p = { 1, 1, -1 };//第一個點前驅設為-1,以便後面打印迷宮 55 maze[p.row][p.col] = 2;//遍歷過的點設置為2 56 PSeqQueue S = Init_SeqQueue(); 57 In_SeqQueue(S,p); 58 while (!Empty_SeqQueue(S)) 59 { 60 Out_SeqQueue(S,&p); 61 if (p.row == MAX_ROW - 2 && p.col == MAX_COL - 2) 62 break; 63 if (p.col + 1< MAX_COL-1 && maze[p.row][p.col + 1] == 0) 64 visit(p.row, p.col + 1,S); 65 if (p.row + 1< MAX_ROW-1 && maze[p.row + 1][p.col] == 0) 66 visit(p.row + 1, p.col,S); 67 if (p.col - 1 >= 1 && maze[p.row][p.col - 1] == 0) 68 visit(p.row, p.col - 1,S); 69 if (p.row - 1 >= 1 && maze[p.row - 1][p.col] == 0) 70 visit(p.row - 1, p.col,S); //以上是對迷宮的四個方向進行操作 71 } 72 if (p.row == MAX_ROW - 2 && p.col == MAX_COL - 2)//是否為出口 73 { 74 int count = 3; 75 struct point q = { p.row, p.col, p.pre }; 76 while (q.pre != -1)//按照前驅進行查找 77 { 78 q = S->data[q.pre]; 79 count++; 80 } 81 printf("成功找到最短路徑,路徑倒序輸出:\n"); 82 printf("(%d,%d)\n", p.row, p.col); 83 maze[p.row][p.col] = count; 84 while (p.pre!=-1)//按照前驅進行查找 85 { 86 count--; 87 p = S->data[p.pre]; 88 maze[p.row][p.col] = count; 89 printf("(%d,%d)\n", p.row, p.col); 90 } 91 printf("三秒後打印路徑......\n"); 92 Sleep(3000); 93 print_line(); 94 } 95 96 else { 97 printf("沒有出路\n"); 98 } 99 100 system("pause"); 101 return 0; 102 } 103 //end maze_queue.cpp
************************************************************************************************************
1 //seqqueue.h 2 #include<stdio.h> 3 #include<stdlib.h> 4 #define MAXSIZE 100 5 struct point{ 6 int row, col, pre; 7 }; 8 typedef struct point DataType; 9 typedef struct { 10 DataType data[MAXSIZE]; 11 int front ,rear; 12 }SeqQueue,*PSeqQueue; 13 14 PSeqQueue Init_SeqQueue() 15 { 16 PSeqQueue Q; 17 Q = (PSeqQueue)malloc(sizeof(SeqQueue)); 18 if(Q) 19 { 20 Q->front = 0; 21 Q->rear = 0; 22 } 23 return Q; 24 } 25 26 int Empty_SeqQueue(PSeqQueue Q) 27 { 28 if(Q && Q->front == Q->rear) 29 return 1; 30 else 31 return 0; 32 } 33 34 int In_SeqQueue(PSeqQueue Q,DataType x) 35 { 36 if((Q->rear + 1) % MAXSIZE == Q->front) 37 { 38 printf("隊滿\n"); 39 return 0; 40 } 41 else 42 { 43 Q->rear = (Q->rear + 1) % MAXSIZE; 44 Q->data[Q->rear] = x; 45 return 1; 46 } 47 } 48 49 int Out_SeqQueue(PSeqQueue Q,DataType *x) 50 { 51 if(Empty_SeqQueue(Q)) 52 { 53 printf("隊空"); 54 return 0; 55 } 56 else 57 { 58 Q->front = (Q->front + 1) % MAXSIZE; 59 *x = Q->data[Q->front]; 60 return 1; 61 } 62 } 63 64 int Front_SeqQueue(PSeqQueue Q,DataType *x) 65 { 66 if(Q->front == Q->rear) 67 { 68 printf("隊空\n"); 69 return 0; 70 } 71 else 72 { 73 *x = Q->data[(Q->front + 1) % MAXSIZE]; 74 return 1; 75 } 76 } 77 78 void Distroy_SeqQueue(PSeqQueue *Q) 79 { 80 if(*Q) 81 free(*Q); 82 *Q = NULL; 83 }//end seqqueue.h
4.運行結果:
5.實驗分析與總結:
在求解迷宮問題中,首先是用棧的來實現操作,一步步入棧出棧,最後找到出路,雖然找到的路勁不是最佳路徑,但是這是一種人工智能的算法,符合人的思維方式,是現實生活中人解決迷宮問題的方式;
而用隊列實現迷宮問題的求解時,依次探索路徑放入隊列中,並對每個元素設置好前驅標誌,這樣一直遍歷到終點時,按照前驅進行探索,輸出整個迷宮的倒序,並對這些坐標進行編碼,再一次遍歷迷宮輸出路徑,即隊列實現迷宮的方法;實際操作中,我已開始設置了錯誤的結構,導致好了一天的時間都沒有寫完這個迷宮,我開始認為多分叉的樹型結構可以很好地解決這個問題,但是在最後探索路勁並返回結果時出現了瓶頸,最後推翻了整個結構,正如老師所說,數據結構的精髓是設計好能更好解決問題的結構,是解決問題的關鍵所在。
數據結構設計——用隊列實現迷宮問題的求解