数据结构 - 栈

栈:先进后出的数据结构

实现方式有顺序栈(数组栈)与链式栈,在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
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,509评论 6 504
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,806评论 3 394
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 163,875评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,441评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,488评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,365评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,190评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,062评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,500评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,706评论 3 335
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,834评论 1 347
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,559评论 5 345
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,167评论 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,779评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,912评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,958评论 2 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,779评论 2 354