数据结构-栈

栈(Stack)是限定仅在表尾进行插入或删除操作的线程表。因此对栈来说表尾端有其特殊含义,称为栈顶(top),相应的表头端称为栈底(bottom)。

image

栈是一种后进先出(last in first out)的线性表,简称LIFO。

栈的抽象数据类型定义

package com.codestd.study.stack;

/**
 * 栈ADT
 */
public interface Stack<E> {
    /**
     * 查看栈顶元素,仅仅查看元素,不从栈中取出。
     */
    E peek();

    /**
     * 向栈中添加元素。
     */
    void push(E e);

    /**
     * 取出栈顶元素
     */
    E pop();

    /**
     * 清空栈
     */
    void clear();
    /**
     * 栈中元素的数量,如果栈为空,则返回0
     */
    int size();
    /**
     * 判断栈是否为空
     */
    boolean isEmpty();
    /**
     * 判断栈是否已满
     */
    boolean isFull();
}

栈的表示和实现

前文讲过,计算机存储数据有两种方式,一种是顺序存储,一种是非顺序存储。栈对应两种存储方式有两种实现方式:一种是数组,一种是单向链表。

栈的数组实现

数组实现栈不需要记录栈底,只需要记录栈顶指针就可以了。入栈的时候栈顶指针后移,出栈的时候栈顶指针前移。使用数组实现是比较简单的,也是比较容易实现的。


image
package com.codestd.study.stack;

import java.util.NoSuchElementException;

/**
 * 数组实现栈
 */
public class ArrayStack<E> implements Stack<E> {

    private final int maxSize;
    private final E[] elementData;
    private int top = -1;

    @SuppressWarnings("unchecked")
    public ArrayStack(int maxSize) {
        this.maxSize = maxSize;
        this.elementData = (E[]) new Object[this.maxSize];
    }

    @Override
    public E peek() {
        if (this.isEmpty()) {
            throw new NoSuchElementException("栈空");
        }
        return this.elementData[this.top];
    }

    @Override
    public void push(E e) {
        if (this.isFull()) {
            throw new RuntimeException("栈满");
        }
        this.top++;
        this.elementData[this.top] = e;
    }

    @Override
    public E pop() {
        if (this.isEmpty()) {
            throw new NoSuchElementException("栈空");
        }
        E el = this.elementData[this.top];
        this.elementData[this.top] = null;
        this.top--;
        return el;
    }

    @Override
    public void clear() {
        for (int i = 0; i < this.top + 1; i++) {
            this.elementData[i] = null;
        }
        this.top = -1;
    }

    @Override
    public int size() {
        return this.top + 1;
    }

    @Override
    public boolean isEmpty() {
        return this.size() == 0;
    }

    @Override
    public boolean isFull() {
        return (this.top + 1) == this.maxSize;
    }
}

栈的链表实现

是用链表实现会相对复杂一点。这里我们使用的是单向链表。

与前面讲的单向链表不同,这里我们不再是使用next指向下一个节点,而是使用prev指向上一个节点。然后指针top始终指向最新的节点。如果取出栈顶数据,则指针指向栈顶元素的prev

image

下面我们使用代码来实现。

package com.codestd.study.stack;

import java.util.NoSuchElementException;

/**
 * 链表实现栈
 */
public class LinkedStack<E> implements Stack<E>{

    private Node<E> top;
    private int size;
    private int maxSize = Integer.MAX_VALUE;

    public LinkedStack() {
    }

    public LinkedStack(int maxSize) {
        this.maxSize = maxSize;
    }

    @Override
    public E peek() {
        if (this.isEmpty()) {
            throw new NoSuchElementException("栈中没有元素");
        }
        return this.top.item;
    }

    @Override
    public void push(E e) {
        if (this.isFull()) {
            throw new RuntimeException("栈满");
        }
        if (this.top == null) {
            this.top = new Node<>(e);
        } else {
            Node<E> node = new Node<>(e);
            node.prev = this.top;
            this.top = node;
        }
        this.size++;
    }

    @Override
    public E pop() {
        if (this.isEmpty()) {
            throw new NoSuchElementException("栈中没有元素");
        }
        Node<E> node = this.top;
        this.top = node.prev;
        node.prev = null;
        this.size--;
        return node.item;
    }

    @Override
    public void clear() {
        Node<E> node = this.top;
        while (node != null) {
            Node<E> prev = node.prev;
            node.prev = null;
            node = prev;
        }
        this.top = null;
        this.size = 0;
    }

    @Override
    public int size() {
        return this.size;
    }

    @Override
    public boolean isEmpty() {
        return this.size == 0;
    }

    @Override
    public boolean isFull() {
        return this.size == this.maxSize;
    }

    private static class Node<E> {
        E item;
        Node<E> prev;

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

推荐阅读更多精彩内容

  • 栈与列队 栈是限定仅在表尾进行插入和删除操作的线性表 队列是只允许在一端进行插入操作、而在另一端进行删除操作的线性...
    Longshihua阅读 1,116评论 0 3
  • 栈 栈: 限定仅在表尾进行插入和删除操作的线性表; 后进先出(LIFO)。 在表尾进行操作,表尾是栈顶;最新进栈的...
    IAM四十二阅读 871评论 0 2
  • 本文内容:一、栈1、什么是栈?2、栈的操作集.3、栈的 C 实现.二、队列1、什么是队列?2、队列的操作集.3、队...
    半纸渊阅读 2,094评论 0 4
  • 栈## 栈是一种动态集合,它是一种LIFO(last in first out后进先出)结构栈的实现:(1)数组(...
    陈继科阅读 16,280评论 0 9
  • 栈是限定仅在表尾进行插入和删除操作的线性表。表尾端称为栈顶,表头端称为栈底。不含元素的空表称为空栈。栈是后进先出的...
    yinxmm阅读 1,799评论 0 0