用链表实现栈
一开始在表头插入,就要一直在表头插入
一开始在表尾插入,就要一直在表头插尾
表头当栈底 也可以把表尾当栈底
实现的测试代码笔记如下:
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("内存分配失败! "); 79 } 80 else 81 { 82 printf("内存分配成功! "); 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