数据结构 - 栈

栈:先进后出的数据结构

实现方式有顺序栈(数组栈)与链式栈,在Java代码中例如ArrayList ,LinkedList都已经实现了该数据结构。方法的调用也是一种入栈出栈的行为。

1链式栈实现代码

public class LinkStack <T>{
    // 定义一个内部Node,Node实例表示链栈的节点
   private class Node{
       //保存节点的数据
       private  T data;
       // 指向下一个节点的引用
       private Node next;

       public Node(){

       }

       public Node(T data,Node next){
           this.data = data;
           this.next = next;
       }
   }
   // 保存该栈的栈顶元素
   private Node top;
   // 保存该栈中包含的节点数
   private int size;

   public LinkStack(){
       top = null;
   }

   public LinkStack(T element){
       top = new Node(element, null);
       size++;
   }
   // 返回栈长度
   public int length(){
       return size;
   }

    // 进栈
    public void push(T element){
       top = new Node(element,top);
       size++;
    }
    // 出栈
    public T pop(){
       Node oldTop = top;
       top  = top.next;

       oldTop.next = null;
       size--;
       return oldTop.data;
    }
    // 访问栈顶元素,不删除元素
    public T peek(){
       return top.data;
    }
    // 判断栈是否为空栈
    public boolean empty(){
       return size == 0;
    }
    // 清空栈
    public void clear(){
       top = null;
       size = 0;
    }

    @Override
    public String toString(){

       if(empty()){
           return "[]";
       }else{
           StringBuilder sb = new StringBuilder("[");
           for(Node current = top; current !=null; current=current.next){
               sb.append(current.data.toString()+",");
           }
           int len = sb.length();
           return sb.delete(len -2,len).append("]").toString();
       }
    }
}

测试代码

public class LinkStackTest {
    public static void main(String[] args) {
        LinkStack<String> stack = new LinkStack<String>();
        stack.push("1aab");
        stack.push("2aa");
        stack.push("3aa");
        stack.push("4aa");
        stack.push("5aa");
        stack.push("6aa");
        System.out.println(stack);
        System.out.println("栈顶元素"+stack.peek());
        System.out.println(""+stack.pop());
        System.out.println(""+stack.pop());
        System.out.println(""+stack.pop());
        System.out.println(""+stack);

    }
}

链式栈 采用了链表形式,内部类Node中维护了一个数据节点,以及下一个节点的引用。所以每次添加值的时候都会先判断当前的栈是否有元素,如果没有直接放入,如果有就将现有栈内元素添加到需要放入的元素的next节点上。

2 顺序栈

public class SequenceStack<T> {

        private final int DEFAULT_SIZE = 10;
        private int capacity;// 保存当前数组长度
        private int capacityIncrement = 0;// 数组长度不够时,程序每次增加的数组长度
        private Object[] elementData;// 保存顺序栈的数据元素
        private int size = 0;// 保存顺序栈中元素的个数

        // 以默认长度创建空的顺序栈
        public SequenceStack() {
            capacity = DEFAULT_SIZE;
            elementData = new Object[capacity];
        }

        // 以一个初始化元素创建顺序栈
        public SequenceStack(T element) {
            this();
            elementData[0] = element;
            size++;
        }

        /**
         * 以指定长度创建顺序栈
         *
         * @param element
         *            指定顺序栈中的第一个元素
         * @param initSize
         *            指定顺序栈的底层数组的长度
         */
        public SequenceStack(T element, int initSize) {
            this.capacity = initSize;
            elementData = new Object[capacity];
            elementData[0] = element;
            size++;
        }

        /**
         * 以指定长度创建顺序栈,同时指定底层数组增量
         *
         * @param element
         *            指定顺序栈中的第一个元素
         * @param initSize
         *            指定顺序栈的底层数组的长度
         * @param capacityIncrement
         *            底层数组长度不够时,每次增加的增量
         */
        public SequenceStack(T element, int initSize, int capacityIncrement) {
            this.capacity = initSize;
            this.capacityIncrement = capacityIncrement;
            elementData = new Object[capacity];
            elementData[0] = element;
            size++;
        }

        // 获取顺序栈的长度
        public int length() {
            return size;
        }

        // 入栈
        public void push(T element) {
            this.ensureCapacity(size + 1);

            // 将元素放到数组,同时让长度+1
            elementData[size++] = element;
        }

        // 保证底层数组的长度
        private void ensureCapacity(int minCapacity) {

            // 如果数组的原有长度小于目前所需的长度
            if (minCapacity > capacity) {
                // 如果给定了数组长度增量
                if (capacityIncrement > 0) {
                    while (minCapacity > capacity) {
                        // 不断的将capacity的长度增加,直到大于minCapacity
                        capacity += capacityIncrement;
                    }
                }
                // 若没有给定增量
                else {
                    while (minCapacity > capacity) {
                        // 不断的将capacity加倍,直到大于minCapacity
                        capacity <<= 1;
                    }
                }

                // 将原来的数组的长度变为新的capacity
                elementData = Arrays.copyOf(elementData, capacity);
            }
        }

        // 出栈
        public T pop() {

            // 若当前为空栈,则弹出null
            if (size == 0) {
                return null;
            }

            T oldValue = (T) elementData[size - 1];
            // 释放栈顶元素,同时将长度-1
            elementData[--size] = null;
            return oldValue;
        }

        // 获取栈顶元素
        public T getPeek() {

            // 若当前为空栈,则返回null
            if (size == 0) {
                return null;
            }
            return (T) elementData[size - 1];
        }

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

        // 情况顺序栈
        public void clear() {
            Arrays.fill(elementData, null);
            size = 0;
        }
        @Override
        public String toString() {
            if (size == 0) {
                return "[]";
            } else {
                StringBuilder sb = new StringBuilder("[");
                for (int i = size - 1; i >= 0; i--) {
                    sb.append(elementData[i].toString() + ", ");
                }

                sb.append("]");

                int length = sb.length();

                // 删除多余的“,”和空格
                return sb.delete(length - 3, length - 1).toString();
            }
        }
    }

测试代码

public static void main(String[] args) {
        SequenceStack<String> stack = new SequenceStack<String>();
        stack.push("1");
        stack.push("2");
        stack.push("3");
        stack.push("4");
        stack.push("5");
        stack.push("6");
        stack.push("7");
        stack.push("8");
        stack.push("9");
        stack.push("10");
        stack.push("11");
        stack.push("12");
        stack.push("13");
        stack.push("14");
        stack.pop();
        System.out.println(stack);a
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容