剑指offer——栈

        栈,初听这个词还以为是战斗的战呢。

        经过学习知道了此“栈“非彼战。栈,与我们小时候玩的那个汉诺塔游戏极其相似,最先放的圆盘最后出,最后放的圆盘最先出,汉诺塔的示意图如下图所示:(此图从百度百科截图过来的)

        根据上述的图所示,最上面的那个圆盘要先出去,下面的圆盘才能依次的拿出去,这个就跟我们所学的栈的特性一摸一样,先进后出,后进先出的特性。简而言之,栈的使用便是按照顺序存入的相反的方向取值,栈的实现可以使用数组去实现,也可以使用单链表去实现,这里我使用的是数组来实现的,相比较单链表实现栈,数组实现的栈更利用我们理解。

        首先,我们需要初始化一个栈的存储数组,我们创建一个ArrayStack类,在该类中设置了maxStackSize、top以及arrays[]三个基本属性,maxStackSize代表的是栈的总容量;top代表的是栈的栈顶元素下标,top赋值为-1,这个很好理解,当栈是空的时候,数组里面是没有数据的,因此栈顶的值肯定是-1;arrays[]数组就是栈存储数据的结构,利用ArrayStack类的有参构造函数初始化栈的基本数据,代码如下:

class ArrayStack{
    //栈大小
    private int maxStackSize;
    //栈的存储数组
    private int[] arrayStack;
    //栈顶
    private int top;

    public ArrayStack(int maxStackSize) {
        this.maxStackSize = maxStackSize;
        arrayStack = new int[maxStackSize];
        top = -1;
    }
}

         当实现了栈的基本结构之后,我们需要考虑的就是栈的基本方法,比如栈的数据添加,栈的数据获取,栈的数据遍历等等,接下来我就针对添加、获取、以及遍历三个方法展开实现。

        在对上述三个方法展开分析和实现之前,我们把最通用的两个方法写好,那就是我们判断栈满以及栈空的方法,isEmpty()和isFull()两个方法。栈满的条件是什么呢,根据我们的分析所得,当top == maxStackSize - 1这个添加满足的时候,就表示当前的栈已经存满了数据,无法再继续存新的数据了;那栈空的条件是什么呢,这个更加容易得到,这个条件在上面介绍top为什么赋值-1的时候便解释了,当top == -1这个条件满足时,就是代表栈空的时候。因此,根据上述的话语,代码实现如下:

    //判断栈满
    public boolean isFull(){
        return top == maxStackSize - 1;
    }

    //判断栈空
    public boolean isEmpty(){
        return top == -1;
    }

        在通用的两个方法实现之后,我开始实现栈的数据添加,这个方法实现的逻辑很简单,从数据传入到该方法中首先先判断栈的空间是否已经存满,如果没有,则arrays[++top] = value,为什么arrays的下标时++top,而不是top,因为top是从-1开始的,而数组的下标是从0开始的,所以使用++top。代码实现如下:

    //入栈
    public void push(int item){
        if (isFull()){
            System.out.println("栈满");
            return;
        }
        arrayStack[++top] = item;
    }

        入栈(栈添加数据)的方法实现之后,我们就需要去拿到栈里面的值,我们就需要编写一个获取数据的方法(出栈);出栈的实现逻辑并不复杂,总体来说,是栈的结构并不是很复杂,甚至可以说很简单,哈哈哈哈,出栈的时候,我们第一步是检测栈是否为空,如果不为空,则返回arrays[top--]即可,top--应该很好理解了,获取完这个数据之后我们便下标左移(从栈的角度看就是下标下移)。代码实现如下:
 

    //出栈
    public int pop(){
        if (isEmpty()){
            throw new RuntimeException("栈空");
        }
        return arrayStack[top--];
    }

        最后这个方法都是大家对熟悉的实现方案,遍历,通用for循环,暴力破解的必备神器,也不多说了,就只要记得遍历的时候按照栈的特性遍历,先进后出,后进先出即可,也就是从top开始遍历即可,代码实现如下:
 

    //遍历栈
    public void list(){
        if (isEmpty()){
            System.out.println("栈空");
            return;
        }
        for (int i = top; i >= 0; i--){
            System.out.printf("stack[%d]=%d\n", i ,arrayStack[i]);
        }
    }

        栈的常用方法分解讲解完毕,现下的代码是包括测试和栈的所有代码:

import java.util.*;

/**
 * 栈
 */
public class ArrayStackDemo {
    public static void main(String[] args) {
        ArrayStack arrayStack = new ArrayStack(4);
        char key;
        boolean loop = true;
        Scanner scanner = new Scanner(System.in);
        while (loop){
            System.out.println("s(list):遍历栈");
            System.out.println("e(exit):退出程序");
            System.out.println("a(push):增加栈数据");
            System.out.println("g(pop):获取栈数据");
            System.out.println("请输入您的选择:");
            key = scanner.next().charAt(0);
            switch (key){
                case 's':
                    arrayStack.list();
                    break;
                case 'a':
                    System.out.println("输入一个数");
                    int value = scanner.nextInt();
                    arrayStack.push(value);
                    break;
                case 'g':
                    try{
                        System.out.printf("取出的数据是%d\n",arrayStack.pop());
                    }catch (Exception e){
                        System.out.println(e.getMessage());
                    }
                    break;
                case 'e':
                    scanner.close();
                    loop = false;
                    break;
                default:
                    break;
            }
        }
        System.out.println("程序结束!");
    }
}
class ArrayStack{
    //栈大小
    private int maxStackSize;
    //栈的存储数组
    private int[] arrayStack;
    //栈顶
    private int top;

    public ArrayStack(int maxStackSize) {
        this.maxStackSize = maxStackSize;
        arrayStack = new int[maxStackSize];
        top = -1;
    }

    //判断栈满
    public boolean isFull(){
        return top == maxStackSize - 1;
    }

    //判断栈空
    public boolean isEmpty(){
        return top == -1;
    }

    //入栈
    public void push(int item){
        if (isFull()){
            System.out.println("栈满");
            return;
        }
        arrayStack[++top] = item;
    }

    //出栈
    public int pop(){
        if (isEmpty()){
            throw new RuntimeException("栈空");
        }
        return arrayStack[top--];
    }

    //遍历栈
    public void list(){
        if (isEmpty()){
            System.out.println("栈空");
            return;
        }
        for (int i = top; i >= 0; i--){
            System.out.printf("stack[%d]=%d\n", i ,arrayStack[i]);
        }
    }
}

        此上便是我对栈的理解和用数组模拟实现,如有不对,烦请大佬指正!

        (单链表实现栈,有兴趣的朋友可以尝试着去实现,后续有空的话我会尝试着去实现。)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

super 琪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值