GitHub同步更新(已分类):Data_Structure_And_Algorithm-Review
公众号:URLeisure 的复习仓库
公众号二维码见文末
以下是本篇文章正文内容,下面案例可供参考。
什么是栈?
栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。(百度百科)
(我也不知道这是谁的图。。。。。图片来源:知乎:不淡定的小淡定 侵删)这种后进先出(Last In First Out,LIFO)的线性序列,称为“栈”。
栈也是一种线性表,只不过它是操作受限的线性表,只能在一端进出操作。
进的一端称为栈顶(top),另一端称为栈底(base)。
栈可以用顺序存储,也可以用链式存储,分别称为顺序栈和链栈。
顺序栈概述(图解)
-
顺序栈需要两个指针,base 指向栈底,top 指向栈顶。
-
初始状态 top 指向 base(top -> base)。
顺序栈的基本操作
-
c++ 写法和 java 写法有一定的区别。
-
c++ 首先定义一个结构体,包含两个指针。
c++代码如下(示例):
struct SqStack{
int *base;//栈底指针
int *top;//栈顶指针
};
java代码如下(示例):
private static int[] date;
private static int top;
1. 初始化
-
栈定义好了之后,还要先定义一个最大的分配空间,顺序结构都是如此,需要预先分配空间。
-
初始化一个空栈,动态分配 Maxsize 大小的空间,用 top 和 base 指向该空间的基地址。
c++代码如下(示例):
bool InitStack(SqStack &S){
S.base = new int[Maxsize];//分配空间
if(!S.base){//分配失败
return false;
}
S.top = S.base;//空栈
return true;
}
java代码如下(示例):
public static boolean init() {
date = new int[maxsize];//分配空间
if (date == null) {//分配失败
return false;
}
top = 0;
return true;
}
2. 入栈
-
入栈前判断是否栈满,如果栈已满,则入栈失败。
-
否则将元素放入栈顶,栈顶指针上移一位(top++)。
-
栈顶指针(top)指向栈顶元素的上一位。
c++代码如下(示例):
bool Push(SqStack &S,int e){//插入e为新的栈顶元素
if(S.top-S.base == Maxsize){
return false;
}
*S.top = e;
S.top ++;//top指针上移
return true;
}
java代码如下(示例):
public static boolean push(int e) {//插入e为新的栈顶元素
if (top == maxsize - 1) {
return false;
}
date[top++] = e;//top指针上移
return true;
}
3. 出栈
-
出栈前判断是否栈空,如果栈是空的,则出栈失败;
-
否则栈顶指针向下移动一个位置(top–),将栈顶元素暂存给一个变量。
-
先将栈顶指针下移得到栈顶元素,再“删除”(直接忽视该元素,下次进栈会覆盖该元素)栈顶元素 。
c++代码如下(示例):
bool Pop(SqStack &S,int &e){//暂存到变量e中
if(S.top == S.base){//栈空
return false;
}
e = *(--S.top);//栈顶指针--,将最新的栈顶元素付给e
return true;
}
java代码如下(示例):
public static int pop() {
if (top == 0) {//栈空
return -1;
}
return date[--top];
}
4. 取栈顶
-
取栈顶和出栈不同。
-
取栈顶元素只是把栈顶元素复制一份,栈顶指针未移动,栈内元素个数未变。
c++代码如下(示例):
int GetTop(SqStack S){
if(S.top != S.base){//栈非空
return *(S.top-1);
}
return -1;
}
java代码如下(示例):
public static int getTop() {
if (top == 0) {
return -1;
}
return date[top - 1];
}
5. 释放内存
- c++需要手动释放内存,而java不需要。
c++代码如下(示例):
void DestroyList(SqStack &S) {
if (S.top || S.base) {
delete S.top;
delete S.base;
}
}
完整代码
c++代码如下(示例):
#include<iostream>
using namespace std;
#define Maxsize 100
struct SqStack {
int *base;
int *top;
};
bool InitStack(SqStack &S) {
S.base = new int[Maxsize];
if (!S.base) {
return false;
}
S.top = S.base;
return true;
}
bool Push(SqStack &S, int e) {
if (S.top - S.base == Maxsize) {
return false;
}
*S.top = e;
S.top++;
return true;
}
bool Pop(SqStack &S, int &e) {
if (S.top == S.base) {
return false;
}
e = *(--S.top);
return true;
}
int GetTop(SqStack S) {
if (S.top != S.base) {
return *(S.top - 1);
}
return -1;
}
void DestroyList(SqStack &S) {
if (S.top || S.base) {
delete S.top;
delete S.base;
}
}
int main() {
SqStack S;
int n, x;
InitStack(S);
cout << "请输入元素个数:" << endl;
cin >> n;
cout << "依次输入元素:" << endl;
while (n--) {
cin >> x;
Push(S, x);
}
cout << "依次出栈:" << endl;
while (S.top != S.base) {
cout << GetTop(S) << endl;
Pop(S, x);
}
DestroyList(S);
}
java代码如下(示例):
import java.util.Scanner;
public class A {
private static final int maxsize = 100;
private static Scanner input = new Scanner(System.in);
private static int[] date;
private static int top;
public static boolean init() {
date = new int[maxsize];
if (date == null) {
return false;
}
top = 0;
return true;
}
public static boolean push(int e) {
if (top == maxsize - 1) {
return false;
}
date[top++] = e;
return true;
}
public static int pop() {
if (top == 0) {
return -1;
}
return date[--top];
}
public static int getTop() {
if (top == 0) {
return -1;
}
return date[top - 1];
}
public static void main(String[] args) {
int n, x;
init();
System.out.println("输入元素个数");
n = input.nextInt();
System.out.println("依次输入元素");
while (n-- > 0) {
x = input.nextInt();
push(x);
}
System.out.println("依次出栈");
while (top > 0) {
System.out.println("栈顶元素为" + getTop());
System.out.println("出栈元素为" + pop());
}
}
}
总结
-
羽毛球入筒的图很好地反映了栈的
后进先出
性质。 -
人为规定栈不允许在中间查找、取值、插入、删除等操作。
-
顺序栈本身是顺序存储的,如果偏要从中间取一个元素,也是可以实现的,但就不是栈了。
关注公众号,感受不同的阅读体验
下期预告: 双向链表