数据结构与算法学习总结(三)——栈的类定义与实现方式

前面已经提及了多次,栈是一种操作受限的线性表,其操作的规则是后进先出(Last In First Out),栈的主要操作有进栈(PUSH)、出栈(POP),主要应用有表达式求值(下篇博客会详细剖析前缀、中缀、后缀表达式与栈的应用)、消除递归、深度优先搜索等。

抽象数据类型

这回开始用Java来编写了,应该更容易看懂了。

package top.zhanglugao.stack;

/***
 * 栈的抽象数据类型
 * @author zhanglugao
 */
public interface Stack<T> {
    void clear();               //清空栈
    boolean push(T t);          //元素入栈
    T pop();                    //获取栈顶元素并弹出
    T top();                    //获取栈顶元素不弹出
    boolean isEmpty();          //判断栈是否为空栈
    boolean isFull();           //判断栈是否已满
}

实现方式

1.顺序表实现栈-顺序栈(Array Based Stack)

使用向量实现,本质上是顺序表的简化版,需要确定哪一端作为栈顶。

1⃣️ 类定义:

package top.zhanglugao.stack;

public class ArrayStack<T> implements  Stack<T>{

    private int mSize;                          //栈存放元素的最大值
    private int top;                            //栈顶元素位置
    T[] st;                                     //实际存放元素的数组

    public ArrayStack(int size){
        st= (T[]) new Object[size];             //初始化数据
    }

    /***
     * 清空栈
     */
    public void clear() {
        st=(T[]) new Object[mSize];
        top=-1;
    }

    /***
     * 获得栈顶元素但不弹出
     * @return
     */
    public T top() {
        return st[top];
    }

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

    public boolean isFull() {
        if(top==mSize-1)return true;
        return false;
    }
}

 2⃣️ 顺序栈的溢出

上溢:当栈中元素已满,继续往栈中添加元素时发生的现象。

下溢:对空栈执行出栈操作时产生的现象

3⃣️ 入栈(PUSH)与出栈(POP)方法的详细实现

    /***
     * 元素入栈
     * @param t 要入栈的元素
     * @returnt
     */
    public boolean push( T t ) {
        //先判断栈是否已满  已满的标识是top=mSize-1
        if(top==mSize-1){
            System.out.println("栈已满,无法继续添加");
            return false;
        }
        //进行添加  处理过程是把t存入数组top+1的位置  再将top值加1
        st[top+1]=t;
        top++;
        return true;
    }

    /**
     * 获得栈顶元素并弹出
     * @return
     */
    public T pop() {
        if(top==-1){
            System.out.println("栈空,无法获取");
            return null;
        }
        //栈顶元素为st[top]  取出来后将st[top]置为null 再将top的值-1
        T t=st[top];
        st[top]=null;
        top--;
        return t;
    }

2.单链表实现栈-链式栈(Linked Stack)

用单链表方式存储,其中指针的方向是由栈顶向下链接。

1⃣️ 类定义:

package top.zhanglugao.stack;

/***
 * 链式表实现栈  因为java中没有指针  Link类直接记录下个元素的内容
 * @param <T>
 */
public class LinkedStack<T> implements Stack<T> {

    private int size;                   //栈内元素数目
    private Link<T> top;                //栈顶元素

    public void clear() {
        size=0;
        top=null;
    }


    /**
     * 获取栈顶元素不弹出
     * @return
     */
    public T top() {
        return top.getData();
    }

    /***
     * size=0的情况下 栈为空
     * @return 栈是否为空
     */
    public boolean isEmpty() {
        return size==0;
    }

    /**
     * 单链表组成的栈 可以不用关注栈是否满
     * @return false
     */
    public boolean isFull() {
        return false;
    }

    public static void main(String[] args) {
        LinkedStack<Integer> linkedStack=new LinkedStack<Integer>();
        linkedStack.push(1);
        linkedStack.push(2);
        linkedStack.push(3);
        linkedStack.push(4);
        int res=linkedStack.top();
        System.out.println("栈顶元素为:"+res);
        int res2=linkedStack.pop();
        System.out.println("栈顶元素为:"+res2);
        System.out.println(linkedStack.top());
    }
}

class Link<T> {
    private T data;
    private Link<T> next;

    public Link(T data,Link<T> next){
        this.data=data;
        this.next=next;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }

    public Link<T> getNext() {
        return next;
    }

    public void setNext(Link<T> next) {
        this.next = next;
    }
}

2⃣️ 入栈与出栈方法的实现

    /***
     * 将元素t压入栈顶
     * @param t
     * @return
     */
    public boolean push(T t) {
        //新建Link<T> next域链接的是当期top 再将top指向新建的Link<T>
        Link<T> newElement=new Link<T>(t,top);
        top=newElement;
        size++;
        return true;
    }

    /**
     * 获取栈顶元素并弹出
     * @return
     */
    public T pop() {
        if(size==0){
            System.out.println("栈空,无法获取");
            return null;
        }
        //获取栈顶元素后,将top指向top的next节点 size减一
        T data=top.getData();
        top=top.getNext();
        size--;
        return data;
    }

3.顺序栈与链式栈的比较

时间效率:所有操作都只需要常数时间,时间复杂度为O(1),在时间效率上顺序栈与链式栈难分伯仲

空间效率:顺序栈需要说明一个固定的长度,链式栈的长度可变,但增加了指针域的结构性开销

在实际应用中,顺序栈比链式栈用的更广泛,顺序栈更容易读取栈定位置,进行相对位移,快速定位并读取栈的内部元素。

顺序栈读取内部元素的时间为O(1),链式栈因为要沿着指针链游走,时间为(n),虽然一般来说,栈是不允许读取内部元素的。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值