今天貼出一個迷宮算法,所謂迷宮,既然用一個二維數組來描述,牆用0X2A表示,不能走,起點給定一個坐標,終點為一個給的確定的值。使用了圖論的深度優先遍歷,自己定義了一個路徑棧,下面上代碼
1 #include "stdafx.h" 2 #include "windows.h" 3 4 bool findNext(int row, int col); //主要尋路函數,row,col分別為需要確定的行列坐標 5 void MyNodePush(int row, int col); //路徑值入棧 6 void MyNodePop(); //路徑出棧 7 void MyDodeDelete();//最后的清理函數,用於清除路徑棧 8 bool isValidPoint(int row, int col); //判斷當前點是否為有效點 9 void DisPlay();//打印路徑 10 typedef struct _NODE //自定義的結點,棧用雙向鏈表來構造 11 { 12 int row; 13 int rol; 14 struct _NODE *NextNode; 15 struct _NODE *BackNode; 16 }NODE, *PNODE; 17 18 19 BYTE myStr[11][16] = { 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x20, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2A, 0x2A, 0x2A, 0x2A, 20 0x20, 0x2A, 0x2E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2E, 0x2E, 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2A, 0x20, 0x2A, 0x2E, 0x2E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2E, 0x2A, 21 0x20, 0x20, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2A, 0x2A, 0x20, 0x2A, 0x2A, 0x2A, 0x2A, 0x2E, 0x2A, 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2A, 0x2A, 0x2A, 22 0x2A, 0x20, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2A, 0x2E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x20, 0x20, 0x2A, 0x2E, 0x2A, 0x2A, 0x2A, 0x2E, 0x2E, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2E, 0x2A, 23 0x20, 0x2A, 0x2E, 0x2E, 0x2A, 0x2A, 0x2A, 0x2E, 0x2A, 0x2A, 0x2E, 0x2A, 0x2A, 0x2A, 0x2E, 0x2A, 0x43, 0x2E, 0x2E, 0x2A, 0x2A, 0x2A, 0x2A, 0x2E, 0x2E, 0x2E, 0x2E, 0x2A, 0x58, 0x2E, 0x2E, 0x2A, 24 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A, 0x2A}; 25 //迷宮,0x2a為牆 0x58為終點, 26 27 PNODE HeadNode;//棧底指針 28 PNODE CurrentNode;//棧頂指針 29 int _tmain(int argc, _TCHAR* argv[]) 30 { 31 HeadNode = (PNODE)malloc(sizeof(NODE)); //為頭結點分配內在 32 memset(HeadNode, -1, sizeof(NODE)); 33 CurrentNode = HeadNode;//棧底棧頂指針初始時為重合 34 35 if (findNext(1, 0))//開始尋路,初始位置為(1,0) 36 { 37 DisPlay(); 38 } 39 else 40 { 41 printf_s("no way to get out from the maze"); 42 } 43 44 /* 45 MyNodePush(1, 2); 46 MyNodePop(); 47 MyNodePush(1, 2); 48 MyNodePush(1, 2); 49 MyNodePop(); 50 MyNodePush(1, 2); 51 */ 52 MyDodeDelete(); 53 system("pause"); 54 return 0; 55 } 56 bool findNext(int row, int col) 57 { 58 MyNodePush(row, col); //將此點入棧 59 if (myStr[row][col] == 0x58) //判斷是否為終點是的話返回正確 60 return true; 61 if (!isValidPoint(row, col)) //如果是牆或者超過了迷宮范圍則該點出棧並返回錯 62 { 63 MyNodePop(); 64 return false; 65 } 66 if (findNext(row - 1, col) || findNext(row + 1, col) || findNext(row, col - 1) || findNext(row, col + 1))//遞歸的尋找該點的上下左右四個點,只要有一個點返回真則可以判斷路徑為真,因為只有當點為終點的時候才會返回真,這里可以優化,由那一點走過來可以不用尋找
67 { 68 return true; 69 } 70 else 71 { 72 MyNodePop();//如果從該點上下左右四個點出發的路徑都不能找到終點,則該點不可能位於正確路徑上。 73 return false; 74 } 75 } 76 void MyNodePush(int row, int col) 77 { 78 PNODE NewNOde =(PNODE) malloc(sizeof(NODE)); 79 NewNOde->row = row; 80 NewNOde->rol = col; 81 NewNOde->NextNode = NULL; 82 NewNOde->BackNode = CurrentNode; 83 CurrentNode->NextNode = NewNOde; 84 CurrentNode = NewNOde; 85 } 86 void MyNodePop() 87 { 88 if (CurrentNode != HeadNode) 89 { 90 CurrentNode->BackNode->NextNode = NULL; 91 PNODE temp = CurrentNode->BackNode; 92 free(CurrentNode); 93 CurrentNode = temp; 94 } 95 96 } 97 void MyDodeDelete() 98 { 99 if (CurrentNode == HeadNode) 100 return; 101 PNODE nodeToDelete = HeadNode; 102 while (true) 103 { 104 PNODE temp = nodeToDelete; 105 if (nodeToDelete->NextNode == NULL) 106 { 107 free(nodeToDelete); 108 break; 109 } 110 nodeToDelete = nodeToDelete->NextNode; 111 free(temp); 112 } 113 } 114 bool isValidPoint(int row, int col) 115 { 116 if (row < 0 || row>10 || col < 0 || col>15)//這里根據是否是牆,或者超過迷宮邊界判斷 117 return false; 118 if (myStr[row][col] == 0x2a) 119 return false; 120 PNODE temp = HeadNode; 121 while (temp->NextNode!=NULL)//這里遍歷已經訪問過的結點,如果已訪問過,則返回錯誤 122 { 123 if (row == temp->row && col == temp->rol) 124 return false; 125 temp = temp->NextNode; 126 /* 127 if (temp->NextNode == NULL) 128 { 129 if (row == temp->row && col == temp->rol) 130 return false; 131 break; 132 } 133 */ 134 } 135 return true; 136 } 137 void DisPlay() 138 { 139 PNODE temp = HeadNode; 140 while (temp->NextNode != NULL) 141 { 142 if (temp !=HeadNode) 143 printf_s("%x,%x\n", temp->row, temp->rol); 144 temp = temp->NextNode; 145 if (temp->NextNode == NULL) 146 { 147 printf_s("%x,%x\n", temp->row, temp->rol); 148 break; 149 } 150 } 151 }
