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

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

 #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. .NET 实用扩展方法

    .NET 实用扩展方法(持续更新...) 1. 字符串转换为可空数值类型(int, long, float...类似) /// <summary> /// 将字符串转换成32位整数,转换失 ...

  2. jsp/servlet学习二之servlet详解

    Servlet API概览 Servlet API有一下四个java包: 1,javax.servlet,其中包含定义servlet和servlet容器之间契约的类和接口. 2,javax.servl ...

  3. CSS布局学习(三) - position属性定义及解释(官网直译)

    static ①元素的位置是在文档正常布局流中的位置. ②设置top right bottom left与z-index无效. ③在未指定position时,static是默认值 以下例子进行说明: ...

  4. gym 101081 E. Polish Fortress 几何

    E. Polish Fortress time limit per test 2.0 s memory limit per test 256 MB input standard input outpu ...

  5. Axure 页面内多组内容切换的实现 + 利用一个内联框架实现百度地图访问

    Axure  页面内多组内容切换的实现,场景:点击某个元件的时候,会显示响应的页面 操作:将显示的页面设置为动态面板,如图所示应该设置动态面板的状态为三个状态,分别为点击qq账号.手机账号.邮箱账号时 ...

  6. 从多个角度来理解协方差(covariance)

    起源:协方差自然是由方差衍生而来的,方差反应的是一个变量(一维)的离散程度,到二维了,我们可以对每个维度求其离散程度,但我们还想知道更多.我们想知道两个维度(变量)之间的关系,直观的举例就是身高和体重 ...

  7. 7.9 GRASP原则九: 隔离变化

    GRASP原则九: 隔离变化  Protected Variations  需求一定会变化的!如何做到以系统的局部变化为代价就可以应对这一点?4.1 GRASP rule9: Protected ...

  8. 有关两个jar包中包含完全相同的包名和类名的加载问题

    首先从表现层介绍,后续后深入原理. 1,先简单介绍maven如何生成jar文件方便测试 <plugin> <artifactId>maven-assembly-plugin&l ...

  9. (译)xDS REST and gRPC protocol

    xDS REST and gRPC protocol 原文地址:xDS REST and gRPC protocol. envoy可通过文件系统.一个或多个管理服务器来发现各种动态资源.这些服务发现和 ...

  10. 通讯录设计ver1.0版本

    表格已经完善! 表格已经完善 接下来就可以考虑数据库和程序的链接了. 指日可待!