数据结构-------栈(数组、链表实现)

  1. 栈是一种先进后出的数据结构,是一种只能在一端进行插入和删除操作的线性表。

  2. 它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据(最后一个数据被第一个读出来)。

  3. 数据进入到栈的动作为压栈(入栈),数据从栈中出去的动作为出栈。

  4. 原理图:
    在这里插入图片描述

  5. 栈是一种逻辑结构,具体存储实现是考虑物理存储结构,即顺序存储结构(数组)和链式存储结构(链表)。

  6. 链表实现栈:

    import java.util.Iterator;
    
    /**
     * @author JIN
     * @description 栈
     **/
    public class Stack<T> implements Iterable<T>{
        //头节点
        private Node head;
        //栈内个数
        private int N;
    
        public Stack(){
            head = new Node(null,null);
            N = 0;
        }
    
        //判断是否为空
        public boolean isEmpty(){
            return N == 0;
        }
    
        //返回栈中个数
        public int size(){
            return N;
        }
    
        //入栈
        public void push(T t){
            //栈后进的元素是在前面,因此使用头插法。
            head.next = new Node(t,head.next);
            N++;
        }
        //出栈
        public T pop(){
            Node node = head.next;
            //安全性校验
            // 若没有这个校验,栈中若没有元素,即node == null
            //此时node.next将是空指针异常
            if(node == null){
                return null;
            }
            //把第一个元素取出,并让头节点指向第二个节点。
            head.next = node.next;
            N--;
            return node.data;
        }
    
        class Node{
            private T data;
            private Node next;
    
            public Node(T data, Node next){
                this.data = data;
                this.next = next;
            }
        }
    
        @Override
        public Iterator<T> iterator() {
            return new Iterator<T>() {
                private Node node = head;
    
                @Override
                public boolean hasNext() {
                    return node.next != null;
                }
    
                @Override
                public T next() {
                    node = node.next;
                    return node.data;
                }
            };
        }
    }
    
    
  7. 数组实现栈:

    import java.util.Iterator;
    
    /**
     * @author JIN
     * @description 栈
     **/
    
    public class Stack2<T> implements Iterable<T>{
        
        //数组用于模拟栈
        private T[] data;
        //实际存储的个数
        private int N;
        //数组的容量
        private int size;
    
        //默认构造函数,初始化数组大小为4
        public Stack2(){
            this(4);
        }
        //构造函数,可以设置数组大小
        public Stack2(int size){
            //因为是泛型,不能 new T[size];
            //因此只能先new Object再强转
            this.data = (T[])new Object[size];
            this.size = size;
            N = 0;
        }
        //判断是否为空
        public boolean isEmpty(){
            return N == 0;
        }
        //返回存储的个数
        public int size(){
            return N;
        }
        //入栈
        public void push(T t){
            //扩容
            if(N > size/2){
                size = size<<1;
                resize(size);
    
            }
            //入栈
            data[N++] = t;
        }
        //扩容
        public void resize(int size){
            //存储旧数据
            T[] olddata = data;
            this.data = (T[]) new Object[size];
            //把旧数据复制到新数组上
            for(int i = 0; i < N; i++){
                data[i] = olddata[i];
            }
        }
        //出栈
        public T pop(){
            //若无数据,直接返回
            if(N <= 0){
                return null;
            }
            //若数组大小有100,但是实际存储数据只有2个,那太浪费空间了
            //因此进行缩容,但若频繁扩容缩容会使整体性能下降
            if(N < size/4){
                size = size>>1;
               resize(size);
            }
            return data[--N];
        }
        
    
        @Override
        public Iterator<T> iterator() {
            return new Iterator<T>() {
                private int num = N;
                @Override
                public boolean hasNext() {
                    return num > 0;
                }
    
                @Override
                public T next() {
                    return data[--num];
                }
            };
        }
    }
    
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值