1、抽象数据类型

栈是一种特殊的线性表,其插入和删除操作只能在线性表的一端进行。允许操作的一端称为栈顶(top),不允许操作的一端称为栈底(bottom),若栈中没有元素,则为空栈。栈是实现嵌套调用机制的基础,典型的比如系统的方法调用。当一个方法A需要调用方法B时,系统会将方法A的相关信息(地址、参数等)入栈,称为保护现场。当方法B执行完毕时,再将方法A出栈,称为恢复现场。

 

由于栈只允许在线性表的一端进行,新入栈的元素即成为栈顶元素,要出栈的元素也是最新入栈的元素,所以栈的操作顺序是后进先出(LIFO)。以下是栈的抽象数据类型定义:

 1 package list.impl;
 2 
 3 /**
 4  * 栈接口
 5  */
 6 public interface IStack<T> {
 7     /**
 8      * 判断栈是否为空
 9      * @return
10      */
11     boolean isEmpty();
12 
13     /**
14      * 元素入栈
15      * @param x
16      */
17     void push(T x);
18 
19     /**
20      * 元素出栈
21      * @return 当前栈顶元素
22      */
23     T pop();
24 
25     /**
26      * 获取栈顶元素,元素不出栈
27      * @return 当前栈顶元素
28      */
29     T get();
30 }

 

同上一篇博文的线性表,我们也用顺序方式和链式来实现栈。

2、栈的顺序表示和实现

栈的顺序操作

类似于线性表的实现,栈的顺序实现是比较简单的,以下是完整的代码:

package list.impl;

/**
 * 栈的顺序表示和实现
 */
public class SeqStack<T> implements IStack<T> {
    private T[] elements;           // 存储栈元素
    private int top;                // 栈顶元素下标

    public SeqStack(int size) {
        elements = (T[])new Object[size];
        top = -1;
    }

    public SeqStack() {
        this(64);
    }

    @Override
    public boolean isEmpty() {
        return top == -1;
    }

    @Override
    public void push(T x) {
        if (x == null)
            return;
        // 若栈满,则扩充容量
        if (top == elements.length - 1) {
            T[] old = elements;
            elements = (T[])new Object[elements.length * 2];
            for (int i = 0, size = old.length; i < size; i++) {
                elements[i] = old[i];
            }
        }

        top++;
        elements[top] = x;
    }

    @Override
    public T pop() {
        return top == -1 ? null : (T)elements[top--];
    }

    @Override
    public T get() {
        return top == -1 ? null : (T)elements[top];
    }
}

栈只在一端进行操作,所以push,get和pop操作的时间复杂度都是O(1)。但是如果当栈需要扩充容量时,push操作的时间复杂度是O(n)。

3、栈的链式表示和实现

 

当栈为空时,top == null。此时头结点的意义不大。实现没有难的地方,以下是完整的代码:

package list.impl;

/**
 * 栈的链式表示和实现
 */
public class LinkedStack<T> implements IStack<T> {
    private Node<T> top;            // 栈顶元素

    public LinkedStack() {
        top = null;
    }

    @Override
    public boolean isEmpty() {
        return top == null;
    }

    @Override
    public void push(T x) {
        if (x != null) {
            top = new Node<T>(x, top);
        }
    }

    @Override
    public T pop() {
        if (isEmpty())
            return null;

        T result = top.data;
        top = top.next;
        return result;
    }

    @Override
    public T get() {
        return top == null ? null : top.data;
    }

    private class Node<E> {
        E data;
        Node<E> next;

        Node(E data, Node<E> next) {
            this.data = data;
            this.next = next;
        }

        Node() {
            this(null, null);
        }
    }
}

 

 

 

posted @ 2014-05-25 11:05  fellow  阅读(223)  评论(0编辑  收藏  举报