图解数据结构——栈的定义与栈的基本操作

203 阅读2分钟

栈在生活中的实例:

在了解栈之前先给大家看几个生活中的实例:

米缸:家里的米缸大家想,我们把米袋从口上拆开,倒进米缸里,这时本来是在袋子上方的米倒进米缸却变成了米缸的最底部的米,而本来在袋子最底部的米却变成了米缸的最上方的米,这是就发现本来在米袋最上方的米变成了最后吃的米,而在最底部米却变成了最先吃的米。

image.png

弹夹上弹:在连戏剧中经常看到一些军人在上弹的时候都是把最先上的子弹压到了弹夹底部,而最后上的子弹变成了弹夹最上方的子弹,所以在开枪的时候最后上的子弹最先出去,最先上的子弹最后出去。

image.png

大家会发现这两个例子会有一个共同的特点:

就是先进的后出,而后进的先出了

栈的定义:

抽象起来:栈是只能在一端进行插入或删除操作的线性表,在表中允许进行插入或者删除操作的称为栈顶。栈顶的当前位置是动态的,由一个称为栈顶指针的位置指示器来指示。栈的另一端称为栈底,当栈中没有元素时称为空栈。栈的插入操作通常称为进栈或者入栈,栈的删除操作通常称为出栈或者退栈

综合理解:上面的例子把米导入米缸、把子弹装入弹夹就称之为入栈;而把米从米缸中取出、把子弹从弹夹中打出称之为出栈;米缸没有米、弹夹没有子弹称为空栈。

今天先来学习顺序栈:

顺序栈:

什么是顺序栈?

顾名思义:采用顺序存储的栈称为顺序栈。

顺序栈的示意图

image.png

创建顺序栈

public class SqStackNode<E> {
    int initCaption =10;         \\栈的初始容量
    E data[];                    \\栈中的数据
    int caption;                 \\栈的容量
    int top;                     \\栈顶的指针
    public SqStackNode(){        \\构造方法
        this.caption = initCaption;
        data = (E[]) new Object[caption];
        this.top =-1;
    }
 }   

顺序栈的基本操作

修改栈的容量

思路:1:首先创建一个新的顺序栈表,将原有的栈表的数据加入到新栈表中,再将传进来参数作为新栈的容量 让以前的链表名指向新的链表地址。

public void updateCaption(int caption){                //修改栈容量
    E newData[] = (E[]) new Object[caption];
    for (int i = 0; i < data.length; i++) {
        newData[i] = data[i];
    }
    this.caption = caption;
    data= newData;
}

图解

未进行扩容之前的栈

image.png

图解

扩容之后的栈,data指向新栈

image.png

判断栈是否为空

写代码之前我们首先看一下空栈图,当栈中没有数据时栈顶的指针为-1

image.png 所以

/*
 * 1:判断栈是否为空:因为top指针是栈顶指针、所以只要当栈顶指针为-1说明栈里无数据也就是空栈
 * */
public boolean isEmpty(){
    if (top==-1) return true;
    return false;
}
判断是否为栈满

当栈顶指针top=栈的容量 caption -1 时代表栈满

/*
 * 2:判断是否为栈满
 * */
public boolean isFull(){
    if (this.top==this.caption) return true;
    return false;
}

图解

image.png

入栈

思路:因为栈的操作只能从栈顶所以我们入栈时首先判断栈是否为满的状态,若为满栈扩容再进行添加,不满直接添加。直接将值赋值给top+1位置,然后让top++;

/*
* 3:入栈:首先判断是否栈满,若栈满扩容栈容量
* */

public void push(E data){
    if (isFull()){
        updateCaption(caption*2);
    }
    this.data[top+1] = data;
    top++;
}

图解

image.png

image.png

出栈:

首先判断栈是否为Null,若为空抛出异常告知栈为空,若不为空从栈顶取出,后将top--; 若栈容量大于初始容量,并且栈中的实际元素个数不足容量的四分之则进行减半。

/*
* 4:出栈:首先判断栈是否为Null,若为空抛出异常告知栈为空,若不为空从栈顶取出,后将top--;
* 若栈容量大于初始容量,并且栈中的实际元素个数不足容量的四分之则进行减半
* */
public E pop(){
    if (isEmpty()){
        throw  new RuntimeException("栈为空");
    }
     E temp = data[top];
    top--;
    if(caption>initCaption&&top<(caption/4)){
        caption = caption/2;
    }
    return temp;
}

图解:

image.png

取栈顶元素

这个没啥说的:只需要输出栈顶即可不需要top--

/*
* 5:取栈顶元素
* */
public E peck(){
    if (isEmpty()){
        throw  new RuntimeException("栈为空");
    }
    E temp = data[top];
    return temp;
}