用鏈表實現棧一開始在表頭插入,就要一直在表頭插入一開始在表尾插入,就要一直在表頭插尾表頭當棧底 也可以把表尾當棧底 實現的測試代碼筆記如下: 附: 推箱子實現,代碼筆記如下所示: 最後實現效果如下所示; 2019-04-01 21:33:15 ...
用鏈表實現棧
一開始在表頭插入,就要一直在表頭插入
一開始在表尾插入,就要一直在表頭插尾
表頭當棧底 也可以把表尾當棧底
實現的測試代碼筆記如下:
1 #include<stdio.h> 2 #include<stdlib.h> 3 #include<string.h> 4 5 //節點的結構體 6 typedef struct Node 7 { 8 char *name; 9 struct Node *pNext; 10 }LIST, *PLIST; 11 12 //1.創建“火車頭” 創建一個表頭 13 void CreateListHead(PLIST *p_list) //傳入頭結點指針 給他分配記憶體 14 { 15 //一級指針 形參和實參結合時 16 //PLIST p_list = p_head; 形參和實參結合時候的賦值 17 //p_list 改變 是不影響到p_head 就好像是A給B發送了一個文件 B對文件進行了修改,是不會影響A手中的文件 18 19 //要改變一級指針的實參 函數要傳入一級指針的地址 保存一級指針的地址 要使用二級指針 20 *p_list = (PLIST)malloc(sizeof(LIST)); 21 (*p_list)->pNext = NULL; 22 23 } 24 25 //實現一個棧 26 //2.寫入棧函數 27 void Push_Stack(PLIST p_list, char *name) 28 { 29 //頭插法 30 PLIST node = (PLIST)malloc(sizeof(LIST)); 31 //node->name - name; 可以這麼寫 但是如果存入得扇區記憶體,會被釋放掉 就會出錯 32 node->name = (char *)malloc(sizeof(char)*strlen(name) + 1); 33 strcpy(node->name, name); 34 node->pNext = p_list->pNext; 35 p_list->pNext = node; 36 } 37 38 //3.獲取棧頂元素 39 char * GetStackTop(PLIST p_list) 40 { 41 //如果不是空 就返回頭結點的下一個節點的name 42 PLIST p_Temp = p_list->pNext; 43 if (p_Temp != NULL) 44 { 45 return p_Temp->name; 46 } 47 return NULL; //說明棧是空 48 } 49 50 //4.出棧 51 void Pop_Stack(PLIST p_list) 52 { 53 //相當於刪除結點 之前是頭插法 那麼最後一個在最前面 54 PLIST p_Temp = p_list->pNext; 55 if (p_Temp != NULL) 56 { 57 //p_remp保存第一個節點的地址 58 p_Temp = p_list->pNext; 59 //讓頭結點的pnext連接到第二個節點 60 p_list->pNext = p_Temp->pNext; 61 } 62 free(p_Temp); //釋放記憶體 釋放掉第一個節點 是釋放p_temp裡面所保存的記憶體 而不是釋放指針變數 63 } 64 65 //5.判斷棧是否為空 66 int isEmpty(PLIST p_list) 67 { 68 //如果棧為空 返回1 69 return p_list->pNext == NULL; 70 } 71 72 int main() 73 { 74 PLIST p_head = NULL; //作為鏈表的標記 75 CreateListHead(&p_head); 76 /*if (NULL == p_head) 77 { 78 printf("記憶體分配失敗!\n"); 79 } 80 else 81 { 82 printf("記憶體分配成功!\n"); 83 }*/ 84 85 Push_Stack(p_head, "力"); 86 Push_Stack(p_head, "努"); 87 Push_Stack(p_head, "的"); 88 Push_Stack(p_head, "人"); 89 Push_Stack(p_head, "何"); 90 Push_Stack(p_head, "任"); 91 Push_Stack(p_head, "於"); 92 Push_Stack(p_head, "亞"); 93 Push_Stack(p_head, "不"); 94 Push_Stack(p_head, "的"); 95 Push_Stack(p_head, "出"); 96 Push_Stack(p_head, "付"); 97 while (!isEmpty(p_head)) 98 { 99 printf("%s", GetStackTop(p_head)); 100 Pop_Stack(p_head); 101 } 102 103 getchar(); 104 return 0; 105 }
附:
推箱子實現,代碼筆記如下所示:
1 1、main.cpp文件 2 3 //推箱子 4 //操作說明 WASD表示上下左右移動 空格鍵可以退回到上一步 5 #if 1 6 #include<graphics.h> 7 #include<stdio.h> 8 #include <conio.h> 9 10 #include "Stack.h" 11 //地圖 12 int Map[9][8] = { 13 0, 0, 1, 1, 1, 1, 1, 0, 14 1, 1, 1, 0, 0, 0, 1, 0, 15 1, 3, 5, 4, 0, 0, 1, 0, 16 1, 1, 1, 0, 4, 3, 1, 0, 17 1, 3, 1, 1, 4, 0, 1, 0, 18 1, 0, 1, 0, 3, 0, 1, 1, 19 1, 4, 0, 7, 4, 4, 3, 1, 20 1, 0, 0, 0, 3, 0, 0, 1, 21 1, 1, 1, 1, 1, 1, 1, 1 22 }; 23 24 //實現退回操作 25 void Retrogress(PLIST p_list) 26 { 27 //1.獲取棧頂數據 28 PLIST p_Temp = GetStackTop(p_list); 29 if (NULL == p_Temp) 30 { 31 return; 32 } 33 for (int i = 0; i < 9; i++) 34 { 35 for (int j = 0; j < 8; j++) 36 { 37 Map[i][j] = p_Temp->p[i][j]; 38 } 39 } 40 Pop_Stack(p_list); //出棧 41 } 42 43 //對於一個游戲1.初始化 載入圖片 44 IMAGE g_box, g_dbox, g_people, g_point, g_wall, g_blank; 45 void Init_Game() 46 { 47 loadimage(&g_box, L"./source/box.jpg"); //相對路徑 48 loadimage(&g_dbox, L"./source/dbox.jpg"); 49 loadimage(&g_people, L"./source/people.jpg"); 50 loadimage(&g_point, L"./source/point.jpg"); 51 loadimage(&g_wall, L"./source/wall.jpg"); 52 loadimage(&g_blank, L"./source/blank.jpg"); 53 } 54 55 //2.載入圖片 56 void Paint_Game() 57 { 58 for (int i = 0; i < 9; i++) 59 { 60 for (int j = 0; j < 8; j++) 61 { 62 switch (Map[i][j]) 63 { 64 case 0: //0表示空地 65 putimage(j * 45, i * 45, &g_blank); 66 break; 67 case 1: // 1表示牆壁 68 putimage(j * 45, i * 45, &g_wall); 69 break; 70 case 3: // 3表示目的地 71 putimage(j * 45, i * 45, &g_point); 72 break; 73 case 4: // 4表示箱子 74 putimage(j * 45, i * 45, &g_box); 75 break; 76 case 5: // 5表示人 77 putimage(j * 45, i * 45, &g_people); 78 break; 79 case 7: // 7表示箱子在目的地 4+3 80 putimage(j * 45, i * 45, &g_dbox); 81 break; 82 case 8: // 8表示人在目的地 5+3 83 putimage(j * 45, i * 45, &g_people); 84 break; 85 } 86 } 87 } 88 } 89 90 //3.實現人物移動 91 void MovePeople(PLIST p_list) 92 { 93 int i, j; 94 for (i = 0; i < 9; i++) 95 { 96 for (j = 0; j < 8; j++) 97 { 98 //找到人的位置 99 if (Map[i][j] == 5 || Map[i][j] == 8) 100 { 101 //if成立說明找到人 102 break; 103 } 104 } 105 if (Map[i][j] == 5 || Map[i][j] == 8) 106 { 107 //if成立說明找到人 108 break; 109 } 110 } 111 switch (getch()) 112 { 113 //表示往左邊移動 114 case 'a': 115 //人的左邊是空地 或者 是目的 116 if (Map[i][j - 1] == 0 || Map[i][j - 1] == 3) 117 { 118 Map[i][j - 1] += 5; //人往左邊移動 119 Map[i][j] -= 5; //人離開了當前位置 120 }//人的左邊是箱子或者是箱子在目的 121 else if (Map[i][j - 1] == 4 || Map[i][j - 1] == 7) 122 { 123 if (Map[i][j - 2] == 0 || Map[i][j - 2] == 3) 124 { 125 Map[i][j - 2] += 4; 126 Map[i][j - 1] += 1; 127 Map[i][j] -= 5; 128 } 129 } 130 //每次移動都要入棧 131 Push_Stack(p_list, Map); 132 break; 133 134 //表示往右邊 135 case 'd': 136 //人的右邊是空地 或者 是目的 137 if (Map[i][j + 1] == 0 || Map[i][j + 1] == 3) 138 { 139 Map[i][j + 1] += 5; //人往左邊移動 140 Map[i][j] -= 5; //人離開了當前位置 141 }//人的右邊是箱子或者是箱子在目的 142 else if (Map[i][j + 1] == 4 || Map[i][j + 1] == 7) 143 { 144 if (Map[i][j + 2] == 0 || Map[i][j + 2] == 3) 145 { 146 Map[i][j + 2] += 4; 147 Map[i][j + 1] += 1; 148 Map[i][j] -= 5; 149 } 150 } 151 //每次移動都要入棧 152 Push_Stack(p_list, Map); 153 break; 154 155 //表示往上邊移動 156 case 'w': 157 //人的上邊是空地 或者 是目的 158 if (Map[i - 1][j] == 0 || Map[i - 1][j] == 3) 159 { 160 Map[i - 1][j] += 5; //人往上邊移動 161 Map[i][j] -= 5; //人離開了當前位置 162 }//人的上邊是箱子或者是箱子在目的 163 else if (Map[i - 1][j] == 4 || Map[i - 1][j] == 7) 164 { 165 if (Map[i - 2][j] == 0 || Map[i - 2][j] == 3) 166 { 167 Map[i - 2][j] += 4; 168 Map[i - 1][j] += 1; 169 Map[i][j] -= 5; 170 } 171 } 172 //每次移動都要入棧 173 Push_Stack(p_list, Map); 174 break; 175 176 //表示什麼往下邊移動 177 case 's': 178 //人的下邊是空地 或者 是目的 179 if (Map[i + 1][j] == 0 || Map[i + 1][j] == 3) 180 { 181 Map[i + 1][j] += 5; //人往左邊移動 182 Map[i][j] -= 5; //人離開了當前位置 183 }//人的下邊是箱子或者是箱子在目的 184 else if (Map[i + 1][j] == 4 || Map[i + 1][j] == 7) 185 { 186 if (Map[i + 2][j] == 0 || Map[i + 2][j] == 3) 187 { 188 Map[i + 2][j] += 4; 189 Map[i + 1][j] += 1; 190 Map[i][j] -= 5; 191 } 192 } 193 //每次移動都要入棧 194 Push_Stack(p_list, Map); 195 break; 196 case VK_SPACE: //空格 197 if (!isEmpty(p_list)) 198 { 199 Retrogress(p_list); 200 Paint_Game(); 201 } 202 } 203 } 204 205 //4.判斷游戲是否結束 206 int isWin() 207 { 208 for (int i = 0; i < 9; i++) 209 { 210 for (int j = 0; j < 8; j++) 211 { 212 if (Map[i][j] == 4) 213 { 214 return 0; 215 } 216 } 217 } 218 return 1; 219 } 220 221 int main() 222 { 223 initgraph(360, 405); //初始化圖形界面 224 Init_Game(); 225 PLIST p_head = NULL; 226 CreateListHead(&p_head); 227 Paint_Game(); 228 while (!isWin()) 229 { 230 Paint_Game(); 231 MovePeople(p_head); 232 } 233 Paint_Game(); 234 getchar();//防止運行到closegraph() 直接退出 看不到效果 235 closegraph(); //關閉圖形界面 236 237 return 0; 238 } 239 240 241 *********************分割線************************ 242 243 244 2、Stack.h文件 245 #include <stdlib.h> 246 #include <stdio.h> 247 /* 248 以後 頭文件是用來聲明函數 或者類 249 */ 250 typedef struct Node 251 { 252 //char *name; //前面是不是講過動態分配二維數組 253 //通過指針數組來實現 254 int **p; //目的:分配二維數組用來保存我的地圖信息 255 struct Node * pNext; 256 }LIST, *PLIST; 257 258 void CreateListHead(PLIST *p_list); 259 260 void Push_Stack(PLIST p_list, int(*pArr)[8]); 261 262 //返回整個結點的內容 263 PLIST GetStackTop(PLIST p_list); 264 265 void Pop_Stack(PLIST p_list); 266 267 int isEmpty(PLIST p_list); 268 269 270 *********************分割線************************ 271 272 273 3、Stack.cpp文件 274 #include "Stack.h" 275 276 void Push_Stack(PLIST p_list, int(*pArr)[8]) 277 { 278 PLIST node = (PLIST)malloc(sizeof(LIST)); 279 //先給二級指針申請記憶體 280 node->p = (int **)malloc(sizeof(int)* 9); // p就相當於是一個 指針數組 int *p[9] 281 for (int i = 0; i < 9; i++) 282 { 283 //通過這個就能夠分配一個二維數組 284 node->p[i] = (int*)malloc(sizeof(int)* 8); 285 } 286 for (int i = 0; i < 9; i++) 287 { 288 for (int j = 0; j < 8; j++) 289 { 290 node->p[i][j] = pArr[i][j]; 291 } 292 //代碼 提升寫代碼能 語法有關 293 //思路 實現功能 首先你要有思路 294 //邏輯 你的方法的邏輯性是否可以 295 // 棧 鏈表 296 } 297 //連接指針 298 node->pNext = p_list->pNext; 299 p_list->pNext = node; 300 // int a[5] 301 // int *a[5] a二級指針 302 } 303 304 PLIST GetStackTop(PLIST p_list) 305 { 306 if (p_list->pNext != NULL) 307 { 308 return p_list->pNext; 309 } 310 return NULL; 311 } 312 313 void Pop_Stack(PLIST p_list) 314 { 315 PLIST p_Temp = NULL; 316 if (p_list->pNext != NULL) 317 { 318 //p_temp保存第一節點的地址 319 p_Temp = p_list->pNext; 320 321 //讓頭節點的pnext連接到第二個結點 322 p_list->pNext = p_Temp->pNext; 323 } 324 //釋放掉第一個結點 325 free(p_Temp); //會釋放p_temp裡面所保存的記憶體 而不是釋放指針變數 326 } 327 328 int isEmpty(PLIST p_list) 329 { 330 return p_list->pNext == NULL; 331 } 332 333 void CreateListHead(PLIST *p_list) //傳入頭節點指針 給它分配記憶體 334 { 335 *p_list = (PLIST)malloc(sizeof(LIST)); 336 (*p_list)->pNext = NULL; 337 }
最後實現效果如下所示;
2019-04-01 21:33:15