c++调用栈库函数_数据结构--栈

写在前面

这一篇我们来学习栈,栈也是非常重要的数据结构,需要好好理解和掌握。

栈初识

栈是一种线性结构,相比与数组,栈对应的操作是数组的子集。不过栈只能从一端添加元素,也只能从一端取出元素(这一端称之为栈顶)。你可以把栈理解为我们常见的竖状容器:

ef475189073100a59bd33519e25a8980.png
2d78e7fa6b70fc3df06304229ef4ecd7.png

记住添加元素和取出元素都只能从栈顶位置开始存取。从图中你也知道栈是一种后进先出的数据结构(先进来的在底部,后面的最先出去)。因此后进先出英文就是Last ln First Out (LIFO)。

栈的应用

你在使用office办公软件的时候,经常会使用撤销操作,Undo操作(撤销)是无处不在的。

假设你需要在word里面打一行字: "沉迷学习无法自拔",然后你一不小心将"无法"打成"不法",然后你就要使用ctrl+Z或者撤销操作,这样"不法"就从栈里面给压出来了,然后你再去写入"无法自拔",这样句子就写完了。如果你想写"沉迷OSC,无法自拔",你就要多次执行撤销操作,最后写入"沉迷OSC,无法自拔"即可。

另一个例子是程序调用的系统栈(这个例子对于理解递归有很大的作用)

我们来看这张图片,这里模拟计算机中程序的调用系统栈:

a9d7ac6d47d4e08e83aef05bdc96478b.png

现在我们开始启动程序:当函数A运行到函数B的时候,会去调用函数B; 而函数B运行到函数C的时候,会去调用函数C;而函数C运行到函数3的时候继续往后走。。。

4fc71e18e37b902dadb36e6a4b043ce2.png

但是这样调用顺序计算机必须要记录下来的,这里就是使用系统栈来完成这个目的的,A2代表运行到A函数第二行,B2代表运行到B函数第二行,然后有了这个系统栈,等到最后程序运行完了以后,就会依次使用出栈的方式开始往前执行程序,最后返回执行A函数,等到A函数执行完发现栈里面是空的,那么整个程序就真的执行完毕了。下面我们使用代码来模拟栈。

关于栈,它是一种非常简单的数据结构,而且里面提供的方法也是有限的,一般是这5种方式:

Stackvoid push(E e); // 向栈中添加元素E pop(); // 弹出栈顶元素E peek( ); // 查看栈顶元素int getSize(); // 获取栈中元素个数boolean isEmpty(); // 判断栈是否为空

这个就不存在直接删除某个元素的操作了,只能依次通过删除栈顶的元素来慢慢实现删除该元素的目的。

其实从用户的角度来说,只要能支持这些操作就行。至于具体的底层实现,用户是不关心的,因为它实际上底层有多种实现方式。

这里我们就把栈定义为一个接口,然后只要能实现这个接口就可以,这也就是我们前面所说的用户只需要具有这些功能即可的目的。在test包下面新建一个Stack包,然后在里面新建一个接口Stack.java文件,里面的代码如下:

 Interface Stack implement ArrayStack int getSize(); boolean isEmpty(); void push(E e); E pop(); E peek();

我们复制之前创建的数组ArrayElement.java文件,因为我们即将实现的ArrayElementStack会用到它。注意前面的addList()方法就是addLast()方法,我打错了,你们记得修改过来哈

前面说过,我们的peek方法是查看栈顶的元素,因此我们需要在ArrayElement.java文件里面新增两个方法,用于获取数组首位和末尾的元素:

 /** * 获取开头位置的元素 * * **/ public E getFirst(){ return get(0); } /** * 获取末尾位置的元素 * * @return 末尾位置的元素 * **/ public E getLast(){ return get(size-1); //这里不可以使用data[size-1],因为假设size==0就会出现不合法的索引号。 }

最后打开Stack包,然后在里面新建ArrayElementStack.java文件,这里我就附上完整的ArrayElementStack文件代码:

package com.suanfa.test.Stack;import com.suanfa.test.Array.ArrayElement;//自己定义的数组栈public class ArrayElementStack implements Stack { //定义一个数组 ArrayElement arrayElement; public ArrayElementStack(){ arrayElement =new ArrayElement<>(); } public ArrayElementStack(int capaciy){ arrayElement =new ArrayElement<>(capaciy); } //实现stack接口中的方法 //实现stack接口中的getSize方法 @Override public int getSize(){ return arrayElement.getSize(); } /** * 实现stack接口中的isEmpty方法 * * @return */ @Override public boolean isEmpty(){ return arrayElement.isEmpty(); } /** * 实现stack接口中的push方法 * * @param e 待添加的元素 * @return */ @Override public void push(E e){ arrayElement.addLast(e); } /** * 实现stack接口中的pop方法 * * @return 栈顶刚删除的元素 */ @Override public E pop(){ return arrayElement.removeLast(); } /** * 实现stack接口中的Peek方法 * * @return 查看栈顶的元素 */ @Override public E peek(){ return arrayElement.getLast(); } /** * * @return 查看栈的容量 */ public int getCapacity(){ return arrayElement.getCapacity(); } /** * * @return 输出栈的元素 */ public String toString(){ //使用StringBuilder;来创建新的字符串对象 StringBuilder res =new StringBuilder(); res.append("Stack"); res.append("["); for(int i=0;i
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值