栈的实现及应用

栈是一种“先入后出”的数据结构,只允许在一端增加和删除数据,其主要操作有push(入栈)、pop(出栈)和peek(查看)三种。在本文采用数组的方式来实现栈,结合下图进行讲解。

  • push(入栈)
    执行该操作时向栈中插入一个数据项。在插入的过程中,top先增加1(向上移动一个单元),再将数据项插入栈中。当栈满时,top等于数组容量的大小size-1,指向栈的最顶端。
    入栈
  • pop(出栈)
    执行该操作时,移除栈顶箭头top所指着的数据项。移除过程中,首先移除由栈顶箭头top所指着的数据项,然后top减1(向下移动一个单元)。当把栈中最后一个数据项移除以后,top为-1,表示此时栈为空。
    出栈
  • peek(查看)
    有时候只需要读取栈顶元素的值,而不需要移除它,peek操作查看的始终是栈最顶端的元素

以下使用java来实现栈,MyStack.java代码如下:

package achieve;

public class MyStack<T> {
    private int maxSize;  //the size of stack array
    private Object[] stackArray;  //stack array
    private int top;  //top of stack

    public MyStack(int size){
        maxSize = size;
        stackArray = new Object[maxSize];
        top = -1;
    }

    public void push(T t){
        if (!isFull()){
            stackArray[++top] = t; //top+1 then insert element
        }else {
            System.out.println("can't push : stack is full.");
        }
    }

    public T pop(){
        if (!isEmpty()){
            return (T)stackArray[top--];  //remove element then top-1
        }else {
            System.out.println("can't pop : stack is empty");
        }
        return  null;
    }

    public T peek(){
        if (!isEmpty()){
            return (T)stackArray[top];
        }else {
            System.out.println("stack is empty");
        }
        return null;
    }

    public boolean isEmpty(){
        return  (top == -1);
    }

    public boolean isFull(){
        return (top == maxSize-1);
    }
}

栈的效率
入栈和出栈的时间复杂度为O(1)。

栈实例1:单词逆序
用栈来实现单词逆序:首先,字母从输入的字符串中一个一个地取出来并压入栈中,接着将它们依次从栈中弹出,并显示出来。因为栈的“后进先出”的特征,所以字母的顺序就颠倒过来了。代码实现如下:

package demo;

import achieve.MyStack;

/**
 * 栈实例1:单词逆序
 */
public class Reverse {

    private String input;
    private String ouput;
    private MyStack<Character> stack;

    public Reverse(String input){
        this.input = input;
        stack = new MyStack<Character>(input.length());
        ouput = "";
    }

    public String doReserve(){
        for (int i = 0;i < input.length();i++){
            stack.push(input.charAt(i));
        }
        while (!stack.isEmpty()){
            ouput += stack.pop();
        }
        return ouput;
    }
}

栈实例2:分隔符匹配
这里我们以分隔符大括号“{ }”、中括号“[ ]”和小括号“( )”为例,每个左分隔符需要和右分隔符匹配。
以 a{b(c[d]e)f} 为例,随着字符串的读取,读到左分隔符,就压入栈中,非分隔符不必压入栈中;而每次读到一个右分隔符,就从栈顶弹出的左分隔符进行匹配。若匹配成功,则继续进行,否则程序停止,匹配结果为false,直到当字符串全部读取完成,且栈为空时,匹配结果才为true。
该过程随字符串的读取栈中的元素变化如下图所示:

实现该过程的java代码如下:

package demo;

import achieve.MyStack;

/**
 * 栈实例2:分隔符匹配
 */
public class BracketCharacter {
    private String input;
    private MyStack<Character> stack;

    public BracketCharacter(String str){
        input = str;
        stack = new MyStack<Character>(input.length());
    }

    public boolean check(){
        int len = input.length();
        for (int i = 0; i < len; i++){
            char ch = input.charAt(i);
            switch (ch){
                case '{':
                case '[':
                case '(':
                    stack.push(ch); //若为左括号,则入栈
                    break;
                case '}':
                case ']':
                case ')':
                    if (!stack.isEmpty()){  //检测到右括号,取栈中最后压入的元素进行校验
                        char begin = stack.pop();
                        if ((ch == '}' && begin != '{') ||
                            (ch == ']' && begin != '[') ||
                            (ch == ')' && begin != '(')){
                            return false;  //不匹配,直接return
                        }
                    }else {  //若栈为空,说明不可能匹配,直接return
                        return false;
                    }
                    break;
                default:
                    break;
            }
        }
        //for循环结束后若栈不为空,即栈中还有左括号为匹配
        if (!stack.isEmpty())
            return false;
        return true;
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值