算法与数据结构 其三 栈的实现

本文介绍了栈的基本概念及其在计算机科学中的应用,详细讲解了通过数组和链表两种方式实现栈的具体方法,并提供了相应的代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

上一小节算法与数据结构 其N 数组和链表 的实现

这一小节就讲讲 栈的实现
什么是栈(Stack)?
这里写图片描述
栈就是一个容器(杯子?碗?随便你想叫什么都行)
先放进去(push)的数据,就只能放在容器底部,最后放进去的数据,就会在最上面。
那我们要获取数据(pop),就只能从最上面的开始拿出来。
如果你只看看,不进去(peek),就只能看到最上面的数据。
Top 就相当于指针吧,用来指向最上面的数据。
我们一般也称这种数据结构为:先进后出

将上面的结构小结下,可以抽象出下面的伪代码

public class Stack(){
    int Top; //模拟指针(当然你觉得没有必要也行)
    E[] e ;// 容器
    Push();//放进去
    Pop();//拿出来
    Peek(); //知道最上面的数据
    ....
}

实现栈,可以通过数组和链表两种形式去实现。

通过数组实现栈

public class MyStackArray<E> {
    //默认长度
    private static int DEFAULT_SIZE ;
    //栈顶指针
    private int top = 0;
    private E[] es;

    public MyStackArray(){
        clear();
    }

    public void clear() {
        //恢复数组默认长度
        top = 0;
        DEFAULT_SIZE=10;
        es = (E[]) new Object[DEFAULT_SIZE];
    }

    //是否为空
    public boolean isEmpty(){
        return size()==0;
    }

    //长度
    public int size(){
        return top;
    }
    //进栈
    public void push(E e){
        //如果大等于 原始容量,扩容
        if(size()>=DEFAULT_SIZE) {
            DEFAULT_SIZE *= 2;
            E[] newEs = (E[]) new Object[DEFAULT_SIZE];
            for (int i = 0; i < top; i++) {
                newEs[i] = es[i];
            }
            es = newEs;
        }
        es[top++]= e;

    }
    //出栈
    public E pop(){
       if(isEmpty()){
           throw new ArrayIndexOutOfBoundsException();
       }
       return es[--top];
    }
    //查看栈顶元素
    public E peek(){
        if(isEmpty()){
            throw new ArrayIndexOutOfBoundsException();
        }
        return es[top-1];
    }

}

通过链表实现栈
(其实这里就是类似实现了单链表,但是不能从随便插入数据)

//备注1
public class MyStackLinked<E> implements Iterable<E> {

    private int theSize;
    //栈顶元素
    private Node<E> top;

    private class Node<E>{
        E e;
        Node<E> prev;

        public Node(E e, Node<E> prev) {
            this.e = e;
            this.prev = prev;
        }
    }


    public MyStackLinked() {
        clear();
    }

    public void clear(){
        top=new Node<>(null,null);
        //当然 top = null;也行
        theSize = 0;
    }

    public int size(){
        return theSize;
    }

    public boolean isEmpty(){
        return size()==0;
    }

    public E top(){
        return pop(size());
    }

    public boolean push(E e){

        return push(e,size());
    }

    public Node<E> get(int index){
        Node<E> node;
        if(index>size() ||index<0){
            throw new IndexOutOfBoundsException();
        }

        node = top;
        for(int i=theSize;i>index;i--){
            node = top.prev;
        }
        return node;
    }

    public boolean push(E e,int size){

        if(size<0 || size>size())
            throw new IndexOutOfBoundsException();
        Node<E> newNode ;
        Node<E> oldNode;

        //插在顶部
        if(size==size()){
            top = new Node<>(e,top);
            theSize++;
            return true;
        }else{
            //新节点的前驱
            newNode = new Node<>(e,get(size-1));
            //节点的前驱
            oldNode = get(size);
            oldNode.prev=newNode;
            theSize++;
            return true;
        }
    }

    public E pop(int index) {
        if(index>size() || index<0)
            throw new IndexOutOfBoundsException();
        Node<E> node =null;
        for(int i=size();i>index;i--){
            //将栈顶删除
            node = get(i);
            node.prev = node;
            theSize--;
        }
        return node.e;
    }

    @Override
    public Iterator<E> iterator() {
        return new MyStackLinkedIterator();
    }

    private class MyStackLinkedIterator<E> implements Iterator<E>{

        private Node<E> node = (Node<E>) top.prev;

        private boolean okRemove = false;
        @Override
        public boolean hasNext() {
            return node!=null;
        }

        //
        @Override
        public E next() {
            if(!hasNext())
                throw new NoSuchElementException();
            E e = (E) node.e;
            node = node.prev;
            okRemove = true;
            return e;
        }

        @Override
        public void remove() {
            if(!okRemove)
                throw new IllegalStateException();
            MyStackLinked.this.top();
            okRemove=false;
        }
    }
}

好了,大概就是这种实现形式。

备注1 :至于这里为什么要实现了 Iterable 接口,那个在上一篇帖子有说明

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值