【数据结构】栈(stack)-顺序栈(动态图解、c++、java)

文章目录

  • 什么是栈?
  • 顺序栈概述(图解)
  • 顺序栈的基本操作
    • 1. 初始化
    • 2. 入栈
    • 3. 出栈
    • 4. 取栈顶
    • 5. 释放内存
  • 完整代码
  • 总结

GitHub同步更新(已分类):Data_Structure_And_Algorithm-Review

公众号:URLeisure 的复习仓库
公众号二维码见文末

以下是本篇文章正文内容,下面案例可供参考。


什么是栈?

栈(stack)又名堆栈,它是一种运算受限的线性表。限定仅在表尾进行插入和删除操作的线性表。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。(百度百科)
【数据结构】栈(stack)-顺序栈(动态图解、c++、java)_第1张图片
(我也不知道这是谁的图。。。。。图片来源:知乎:不淡定的小淡定 侵删)

这种后进先出(Last In First Out,LIFO)的线性序列,称为“栈”。
栈也是一种线性表,只不过它是操作受限的线性表,只能在一端进出操作。
进的一端称为栈顶(top),另一端称为栈底(base)。
栈可以用顺序存储,也可以用链式存储,分别称为顺序栈和链栈

顺序栈概述(图解)

【数据结构】栈(stack)-顺序栈(动态图解、c++、java)_第2张图片

  • 顺序栈需要两个指针,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 指向该空间的基地址。
    【数据结构】栈(stack)-顺序栈(动态图解、c++、java)_第3张图片

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)指向栈顶元素的上一位。

【数据结构】栈(stack)-顺序栈(动态图解、c++、java)_第4张图片

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–),将栈顶元素暂存给一个变量。

  • 先将栈顶指针下移得到栈顶元素,再“删除”(直接忽视该元素,下次进栈会覆盖该元素)栈顶元素 。
    【数据结构】栈(stack)-顺序栈(动态图解、c++、java)_第5张图片

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

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());
        }
    }
}

总结

  • 羽毛球入筒的图很好地反映了栈的后进先出性质。

  • 人为规定栈不允许在中间查找、取值、插入、删除等操作。

  • 顺序栈本身是顺序存储的,如果偏要从中间取一个元素,也是可以实现的,但就不是栈了。


关注公众号,感受不同的阅读体验

请添加图片描述

下期预告: 双向链表

你可能感兴趣的:(数据结构,c++,java,栈,图解法)