用链表实现栈
一开始在表头插入,就要一直在表头插入
一开始在表尾插入,就要一直在表头插尾
表头当栈底 也可以把表尾当栈底

实现的测试代码笔记如下:

 #include<stdio.h>
#include<stdlib.h>
#include<string.h> //节点的结构体
typedef struct Node
{
char *name;
struct Node *pNext;
}LIST, *PLIST; //1.创建“火车头” 创建一个表头
void CreateListHead(PLIST *p_list) //传入头结点指针 给他分配内存
{
//一级指针 形参和实参结合时
//PLIST p_list = p_head; 形参和实参结合时候的赋值
//p_list 改变 是不影响到p_head 就好像是A给B发送了一个文件 B对文件进行了修改,是不会影响A手中的文件 //要改变一级指针的实参 函数要传入一级指针的地址 保存一级指针的地址 要使用二级指针
*p_list = (PLIST)malloc(sizeof(LIST));
(*p_list)->pNext = NULL; } //实现一个栈
//2.写入栈函数
void Push_Stack(PLIST p_list, char *name)
{
//头插法
PLIST node = (PLIST)malloc(sizeof(LIST));
//node->name - name; 可以这么写 但是如果存入得扇区内存,会被释放掉 就会出错
node->name = (char *)malloc(sizeof(char)*strlen(name) + );
strcpy(node->name, name);
node->pNext = p_list->pNext;
p_list->pNext = node;
} //3.获取栈顶元素
char * GetStackTop(PLIST p_list)
{
//如果不是空 就返回头结点的下一个节点的name
PLIST p_Temp = p_list->pNext;
if (p_Temp != NULL)
{
return p_Temp->name;
}
return NULL; //说明栈是空
} //4.出栈
void Pop_Stack(PLIST p_list)
{
//相当于删除结点 之前是头插法 那么最后一个在最前面
PLIST p_Temp = p_list->pNext;
if (p_Temp != NULL)
{
//p_remp保存第一个节点的地址
p_Temp = p_list->pNext;
//让头结点的pnext连接到第二个节点
p_list->pNext = p_Temp->pNext;
}
free(p_Temp); //释放内存 释放掉第一个节点 是释放p_temp里面所保存的内存 而不是释放指针变量
} //5.判断栈是否为空
int isEmpty(PLIST p_list)
{
//如果栈为空 返回1
return p_list->pNext == NULL;
} int main()
{
PLIST p_head = NULL; //作为链表的标记
CreateListHead(&p_head);
/*if (NULL == p_head)
{
printf("内存分配失败!\n");
}
else
{
printf("内存分配成功!\n");
}*/ Push_Stack(p_head, "力");
Push_Stack(p_head, "努");
Push_Stack(p_head, "的");
Push_Stack(p_head, "人");
Push_Stack(p_head, "何");
Push_Stack(p_head, "任");
Push_Stack(p_head, "于");
Push_Stack(p_head, "亚");
Push_Stack(p_head, "不");
Push_Stack(p_head, "的");
Push_Stack(p_head, "出");
Push_Stack(p_head, "付");
while (!isEmpty(p_head))
{
printf("%s", GetStackTop(p_head));
Pop_Stack(p_head);
} getchar();
return ;
}

附:

推箱子实现,代码笔记如下所示:

 、main.cpp文件

 //推箱子
//操作说明 WASD表示上下左右移动 空格键可以退回到上一步
#if 1
#include<graphics.h>
#include<stdio.h>
#include <conio.h> #include "Stack.h"
//地图
int Map[][] = {
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , , ,
, , , , , , ,
}; //实现退回操作
void Retrogress(PLIST p_list)
{
//1.获取栈顶数据
PLIST p_Temp = GetStackTop(p_list);
if (NULL == p_Temp)
{
return;
}
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
Map[i][j] = p_Temp->p[i][j];
}
}
Pop_Stack(p_list); //出栈
} //对于一个游戏1.初始化 加载图片
IMAGE g_box, g_dbox, g_people, g_point, g_wall, g_blank;
void Init_Game()
{
loadimage(&g_box, L"./source/box.jpg"); //相对路径
loadimage(&g_dbox, L"./source/dbox.jpg");
loadimage(&g_people, L"./source/people.jpg");
loadimage(&g_point, L"./source/point.jpg");
loadimage(&g_wall, L"./source/wall.jpg");
loadimage(&g_blank, L"./source/blank.jpg");
} //2.加载图片
void Paint_Game()
{
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
switch (Map[i][j])
{
case : //0表示空地
putimage(j * , i * , &g_blank);
break;
case : // 1表示墙壁
putimage(j * , i * , &g_wall);
break;
case : // 3表示目的地
putimage(j * , i * , &g_point);
break;
case : // 4表示箱子
putimage(j * , i * , &g_box);
break;
case : // 5表示人
putimage(j * , i * , &g_people);
break;
case : // 7表示箱子在目的地 4+3
putimage(j * , i * , &g_dbox);
break;
case : // 8表示人在目的地 5+3
putimage(j * , i * , &g_people);
break;
}
}
}
} //3.实现人物移动
void MovePeople(PLIST p_list)
{
int i, j;
for (i = ; i < ; i++)
{
for (j = ; j < ; j++)
{
//找到人的位置
if (Map[i][j] == || Map[i][j] == )
{
//if成立说明找到人
break;
}
}
if (Map[i][j] == || Map[i][j] == )
{
//if成立说明找到人
break;
}
}
switch (getch())
{
//表示往左边移动
case 'a':
//人的左边是空地 或者 是目的
if (Map[i][j - ] == || Map[i][j - ] == )
{
Map[i][j - ] += ; //人往左边移动
Map[i][j] -= ; //人离开了当前位置
}//人的左边是箱子或者是箱子在目的
else if (Map[i][j - ] == || Map[i][j - ] == )
{
if (Map[i][j - ] == || Map[i][j - ] == )
{
Map[i][j - ] += ;
Map[i][j - ] += ;
Map[i][j] -= ;
}
}
//每次移动都要入栈
Push_Stack(p_list, Map);
break; //表示往右边
case 'd':
//人的右边是空地 或者 是目的
if (Map[i][j + ] == || Map[i][j + ] == )
{
Map[i][j + ] += ; //人往左边移动
Map[i][j] -= ; //人离开了当前位置
}//人的右边是箱子或者是箱子在目的
else if (Map[i][j + ] == || Map[i][j + ] == )
{
if (Map[i][j + ] == || Map[i][j + ] == )
{
Map[i][j + ] += ;
Map[i][j + ] += ;
Map[i][j] -= ;
}
}
//每次移动都要入栈
Push_Stack(p_list, Map);
break; //表示往上边移动
case 'w':
//人的上边是空地 或者 是目的
if (Map[i - ][j] == || Map[i - ][j] == )
{
Map[i - ][j] += ; //人往上边移动
Map[i][j] -= ; //人离开了当前位置
}//人的上边是箱子或者是箱子在目的
else if (Map[i - ][j] == || Map[i - ][j] == )
{
if (Map[i - ][j] == || Map[i - ][j] == )
{
Map[i - ][j] += ;
Map[i - ][j] += ;
Map[i][j] -= ;
}
}
//每次移动都要入栈
Push_Stack(p_list, Map);
break; //表示什么往下边移动
case 's':
//人的下边是空地 或者 是目的
if (Map[i + ][j] == || Map[i + ][j] == )
{
Map[i + ][j] += ; //人往左边移动
Map[i][j] -= ; //人离开了当前位置
}//人的下边是箱子或者是箱子在目的
else if (Map[i + ][j] == || Map[i + ][j] == )
{
if (Map[i + ][j] == || Map[i + ][j] == )
{
Map[i + ][j] += ;
Map[i + ][j] += ;
Map[i][j] -= ;
}
}
//每次移动都要入栈
Push_Stack(p_list, Map);
break;
case VK_SPACE: //空格
if (!isEmpty(p_list))
{
Retrogress(p_list);
Paint_Game();
}
}
} //4.判断游戏是否结束
int isWin()
{
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
if (Map[i][j] == )
{
return ;
}
}
}
return ;
} int main()
{
initgraph(, ); //初始化图形界面
Init_Game();
PLIST p_head = NULL;
CreateListHead(&p_head);
Paint_Game();
while (!isWin())
{
Paint_Game();
MovePeople(p_head);
}
Paint_Game();
getchar();//防止运行到closegraph() 直接退出 看不到效果
closegraph(); //关闭图形界面 return ;
} *********************分割线************************ 、Stack.h文件
#include <stdlib.h>
#include <stdio.h>
/*
以后 头文件是用来声明函数 或者类
*/
typedef struct Node
{
//char *name; //前面是不是讲过动态分配二维数组
//通过指针数组来实现
int **p; //目的:分配二维数组用来保存我的地图信息
struct Node * pNext;
}LIST, *PLIST; void CreateListHead(PLIST *p_list); void Push_Stack(PLIST p_list, int(*pArr)[]); //返回整个结点的内容
PLIST GetStackTop(PLIST p_list); void Pop_Stack(PLIST p_list); int isEmpty(PLIST p_list); *********************分割线************************ 、Stack.cpp文件
#include "Stack.h" void Push_Stack(PLIST p_list, int(*pArr)[])
{
PLIST node = (PLIST)malloc(sizeof(LIST));
//先给二级指针申请内存
node->p = (int **)malloc(sizeof(int)* ); // p就相当于是一个 指针数组 int *p[9]
for (int i = ; i < ; i++)
{
//通过这个就能够分配一个二维数组
node->p[i] = (int*)malloc(sizeof(int)* );
}
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
node->p[i][j] = pArr[i][j];
}
//代码 提升写代码能 语法有关
//思路 实现功能 首先你要有思路
//逻辑 你的方法的逻辑性是否可以
// 栈 链表
}
//连接指针
node->pNext = p_list->pNext;
p_list->pNext = node;
// int a[5]
// int *a[5] a二级指针
} PLIST GetStackTop(PLIST p_list)
{
if (p_list->pNext != NULL)
{
return p_list->pNext;
}
return NULL;
} void Pop_Stack(PLIST p_list)
{
PLIST p_Temp = NULL;
if (p_list->pNext != NULL)
{
//p_temp保存第一节点的地址
p_Temp = p_list->pNext; //让头节点的pnext连接到第二个结点
p_list->pNext = p_Temp->pNext;
}
//释放掉第一个结点
free(p_Temp); //会释放p_temp里面所保存的内存 而不是释放指针变量
} int isEmpty(PLIST p_list)
{
return p_list->pNext == NULL;
} void CreateListHead(PLIST *p_list) //传入头节点指针 给它分配内存
{
*p_list = (PLIST)malloc(sizeof(LIST));
(*p_list)->pNext = NULL;
}

最后实现效果如下所示;

2019-04-01  21:33:15

C++学习(三十七)(C语言部分)之 链式栈(推箱子实现)的更多相关文章

  1. 012-C语言小游戏之推箱子

    012-C语言小游戏之推箱子 一.创建游戏地图   1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 #define ROWS 11 #define COLS 12   char ...

  2. Java开发学习(三十七)----SpringBoot多环境配置及配置文件分类

    一.多环境配置 在工作中,对于开发环境.测试环境.生产环境的配置肯定都不相同,比如我们开发阶段会在自己的电脑上安装 mysql ,连接自己电脑上的 mysql 即可,但是项目开发完毕后要上线就需要该配 ...

  3. 学习笔记:oracle学习三:SQL语言基础之sql语言简介、用户模式

    目录 1.sql语言简介 1.1 sql语言特点 1.2 sql语言分类 1.3 sql语言的编写规则 2.用户模式 2.1 模式与模式对象 2.2 实例模式scott 本系列是作为学习笔记,用于记录 ...

  4. 学习笔记:oracle学习三:SQL语言基础之检索数据:简单查询、筛选查询

    目录 1. 检索数据 1.1 简单查询 1.1.1 检索所有列 1.1.2 检索指定的列 1.1.3 查询日期列 1.1.4 带有表达式的select语句 1.1.5 为列指定别名 1.1.6 显示不 ...

  5. shell学习三十七天----引用

    引用 案例,假设我想输出一个星号(*),使用echo怎样做? echo * 这是肯定不行的,须要将*转移,即:echo \* 这样就引出了引用的概念.所为引用,是用来防止shell将某些你想要的东西解 ...

  6. Salesforce LWC学习(三十七) Promise解决progress-indicator的小问题

    本篇参考:https://developer.salesforce.com/docs/component-library/bundle/lightning-progress-indicator/exa ...

  7. python学习三十七天函数的作用域查找顺序LEGB

    python函数的作用域查找顺序LEGB,分别为 locals  eclosing  globals  builtins .了解作用域的范围,可以更好的操作你想要的业务,分别介绍一下. 1,local ...

  8. 前端学习(三十七)angular(笔记)

    MVC     后台    M         Module             数据层    V         View             视图层    C         Contro ...

  9. C/C++编程笔记:C语言写推箱子小游戏,大一学习C语言练手项目

    C语言,作为大多数人的第一门编程语言,重要性不言而喻,很多编程习惯,逻辑方式在此时就已经形成了.这个是我在大一学习 C语言 后写的推箱子小游戏,自己的逻辑能力得到了提升,在这里同大家分享这个推箱子小游 ...

  10. C语言之推箱子游戏代码

    前言本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理.作者:Yan_Less 正文 新手注意:如果你学习遇到问题找不到人解答,可以点 ...

随机推荐

  1. gets() 与 scanf() 的小尴尬

    gets() 与 scanf() 函数相处呢有点小尴尬的,就是 gets() 在 scanf() 后边就爱捣乱.为什么呢,先了解它们两者之间的异同: 同: 都是可以接受连续的字符数据 并在字符结束后自 ...

  2. sublime汉化

    1.打开sublime使用快捷键 shift+ctrl+p调出package control; 2.键入Package Control:install package 会弹出一个输入框,然后再搜索lo ...

  3. 转 ObjExporter Unity3d导出场景地图寻路

    http://wiki.unity3d.com/index.php?title=ObjExporter

  4. Linux下修改用户的UID、GID

    01.用户的UID和GID不能被占用 [root@26 ~]# id mvpuid=503(mvp) gid=503(mvp) groups=503(mvp) ###假定我需要设置mvp的uid/gi ...

  5. 与vnpy相关的有用博客网址

    https://blog.csdn.net/Trader_Python/article/list/1

  6. 雷林鹏分享:jQuery EasyUI 数据网格 - 创建页脚摘要

    jQuery EasyUI 数据网格 - 创建页脚摘要 在本教程中,我们将向您展示如何在数据网格(datagrid)页脚显示摘要信息行. 为了显示页脚行,您应该设置 showFooter 属性为 tr ...

  7. 亲自打造Deferred对象

    经过对比之后,决心学习jQuery,自己打造一个Deferred对象.var util = require('./util.js');function Callbacks() { var list = ...

  8. MVC实战之排球计分软件(深入了解面向对象编程)

    在此篇博客之前,我已经写了一个实战系列的博客,虽然不太成熟但是相对比较实用,在这篇博客我将继续使用mvc编程此软件. 此篇博客会在一定的时间内完成,此次完成的软件的一个需求是提供给运动员的使用.我将在 ...

  9. sql 中取整,四舍五入取整,向下取整,向上取整。

    SELECT round(52.45, 0) AS round4, round(52.54, 0) AS round5, round(52.45, 1) AS round41, round(52.54 ...

  10. vscode 创建.net core mvc

    cd 进一个文件夹 1,创建一个sln 工程文件  [ dotnet new sln -n Demo1 ] 2,创建一个mvc项目 [ dotnet new mvc -n Demo1.Web ] 3, ...