狗窝:用数组实现一个栈

来源:互联网 发布:在淘宝买机票怎么取票 编辑:程序博客网 时间:2024/04/29 21:28

狗窝:用数组实现一个栈

看过西游记的同学应该记得,有一回,四人被妖怪抓住,要下蒸笼,担心猪八戒皮糙肉厚不容易熟把他放在最底下一格。八戒哇哇大叫。孙悟空却还嘲笑妖怪是雏儿,说皮厚的其实该放在上边才熟的快。小时候看这段,很精彩,但一直没去没验证这个说法的真实性,谁让大师兄看起来很厉害的样子……。哈,扯远了。举这个栗子是想用它引入咱们今天的主题——用数组来实现一个栈。

栈是一种基本的数据结构,具有后进先出(LIFO —— last in - first out)的特性。在生活中的栗子也随处可见,一叠碗、一摞书、妖怪用的蒸笼都是经典的栈结构。那么在程序里如何去实现一个栈呢?要弄清这个问题,我们先要知道栈拥有哪些行为。网上文章不少,我试着用自己的语言再描述一下:栈是一个容器,一般来说容量是固定的,我们把向这个容器中插入一个元素叫作入栈(push),把删除一个元素叫作出栈(pop),不管是入栈还是出栈,你每次的操作都只能在容器最顶上的那个位置进行。

这里写图片描述

基于这些行为,可以定义这样一个接口:

public interface IStack {    /**     * 入栈。先限定类型只能是String,同时不允许插入null     *     * @param value push value     */    void push(@NotNull String value);    /**     * 出栈     */    void pop();    /**     * 清空栈     */    void clean();    /**     * 返回栈大小     *     * @return stack size     */    int size();    /**     * 栈是否为空     *     * @return is empty     */    boolean isEmpty();}

初具雏形了呢,虽然它还什么都不能做。但有了这个框架,就可以一步步往里面填东西了。接下来新建一个类,实现 IStack 接口

public class Stack implements IStack {    private static final int DEFAULT_INCREMENT = 4;    private String[] container;    private int size = 0;    private int top = -1;   // 栈顶索引  public Stack() {        this(DEFAULT_INCREMENT);    }    public Stack(int increment) {        if (increment <= 0) {            throw new IllegalArgumentException("Increment must be greater than zero.");        }        container = new String[increment];    }}    

实现接口方法

 @Override    public void push(@NotNull String value) {        top += 1;        if (top < container.length) {            container[top] = value;        }        // 1.new一个空数组,长度为container.len+1         // 2.把container的元素复制到temp中,并将新元素插入到数组temp尾部        // 3.temp赋给container        else {            String[] temp = new String[container.length + 1];            System.arraycopy(container, 0, temp, 0, container.length);            temp[temp.length - 1] = value;            container = temp;        }        size += 1;    }    @Override    public void pop() {        if (isEmpty()) {            throw new StackOverflowException("The stack is empty");        }        this.container[top] = null;        size -= 1;        top -= 1;    }    @Override    public void clean() {       while (!isEmpty()) {            pop();        }    }    @Override    public int size() {        return size;    }    @Override    public boolean isEmpty() {        return size == 0;    }

现在来测试一下

public static void main(String[] args) {        Stack<String> st1 = new Stack<>();        st1.push("烧麦");        st1.push("豆沙");        st1.push("猪肉大葱");        st1.push("老面馒头");        st1.push("白团子");        st1.pop();        st1.pop();        st1.pop();        st1.set("芹菜香菇包");        outputStackInfo(st1);}

stack info : Stack{container=[烧麦, 芹菜香菇包, null, null, null]}
stack top : 1
stack size : 2
stack empty : false


到这里,我们已经基本上用数组实现了一个栈。为什么说基本上呢?因为我们只实现了接口中的几个方法。至少目前看来,它还存在以下几个缺陷:

  • 从功能上
    1. 只能存储 String 类型,如何利用泛型让它支持多种类型的存储呢。
    2. 从外部无法访问元素,是否需要对外提供 get 方法?另外,是否需要支持循环遍历。
  • 从实现细节上
    1. size 达到数组的长度时,每次增量为 1。
    2. 没有限制栈的 max size。

如果你有兴趣,可以尝试去解决一下。

参考:

  • 《算法导论》第10章:基本数据结构
  • java doc
2 0
原创粉丝点击