java 实现顺序栈和链表栈

栈的主要特点是“后进先出”,即后进栈的元素先被处理。因此,栈又被称为后进先出(last in first out,LIFO)表。它的实现方式主要有顺序栈、链表栈两种。

首先使用接口定义栈的几个方法

public interface StackADT<T> {
    /**
     * 压入栈中一个元素
     *
     * @param element
     */
    public void push(T element);

    /**
     * 弹出栈中一个元素
     *
     * @return
     */
    public T pop();

    /**
     * 查看栈顶的元素
     *
     * @return
     */
    public T peek();

    public boolean isEmpty();

    public int size();

    public String toString();
}
再定义一个异常处理,当栈中元素为空时,弹出栈报此异常
public class EmptyCollectionException extends RuntimeException {
    public EmptyCollectionException(String collection){
        super("The "+collection+" is empty.");
    }
}

顺序栈

实现代码

public class ArrayStack<T> implements StackADT<T> {
    private int DEFAULT_SIZE = 5;
    private int capacity;
    private int top;//该变量为紧跟栈顶元素后的数组索引号,也是栈目前的容量,top-1为栈顶的索引,
    private T[] stack;

    public ArrayStack() {
        capacity = DEFAULT_SIZE;
        top = 0;
        stack = (T[]) (new Object[capacity]);
    }

    public ArrayStack(int initCapity) {
        top = 0;
        capacity = initCapity;
        stack = (T[]) (new Object[capacity]);
    }

    /**
     * 实现步骤:
     * 1、确保该数组不是满的
     * 2、把数组top引用设置为要加入栈中的对象
     * 3、增加top的值
     *
     * @param element
     */
    @Override
    public void push(T element) {
        if (capacity == stack.length) {
            expandCapacity();
        }
        stack[top] = element;
        top++;
    }

    /**
     * 实现步骤:
     * 1、确保栈不为空
     * 2、减小top的计数
     * 3、设置一个临时引用等于stack[top]的元素
     * 4、设置stack[top]为空
     * 5、返回该临时引用
     *
     * @return
     * @throws EmptyStackException
     */
    @Override
    public T pop() throws EmptyStackException {
        if (isEmpty()) {
            throw new EmptyCollectionException("ArrayStack");
        }
        top--;
        T result = stack[top];
        stack[top] = null;
        return result;
    }


    @Override
    public T peek() {
        if (isEmpty()) {
            throw new EmptyCollectionException("ArrayStack");
        }
        return stack[top - 1];
    }

    @Override
    public boolean isEmpty() {
        if (top == 0) {
            return true;
        }
        return false;
    }

    @Override
    public int size() {
        return top;
    }

    @Override
    public String toString() {
        if (top == 0) {
            return "{}";
        } else {
            StringBuilder sb = new StringBuilder("{");
            for (int i = size() - 1; i >= 0; i--) {
                if (stack[i] != null) {
                    if (i != 0) {
                        sb.append(stack[i].toString() + ";");
                    } else {
                        sb.append(stack[i].toString());
                    }
                }
            }
            int len = sb.length();
            return sb.append("}").toString();
        }
    }

    /**
     * 扩容数组
     */
    private void expandCapacity() {
        stack = Arrays.copyOf(stack, stack.length * 2);
    }
}

编写测试顺序栈

public class TestArrayStack {
    public static void main(String[] args) {
        ArrayStack<Integer> arrayStack = new ArrayStack<>();
        arrayStack.push(123);
        arrayStack.push(13);
        arrayStack.push(15);
        arrayStack.push(16);
        arrayStack.push(18);
        System.out.println(arrayStack);

        ArrayStack<Integer> invertStack = new ArrayStack<>();//反转栈
        int length = arrayStack.size();
        for (int i = 0; i <length; i++) {
            invertStack.push(arrayStack.pop());
        }
        System.out.println(invertStack);
        System.out.println(arrayStack.size());
    }
}

输出结果

{18;16;15;13;123}
{123;13;15;16;18}
0

链表栈

首先建一个结点类LinearNode

public class LinearNode<T> {
    private T element;
    private LinearNode<T> next;

    public LinearNode() {
        element = null;
        next = null;
    }

    public LinearNode(T element) {
        this.element = element;
        next = null;
    }

    public T getElement() {
        return element;
    }

    public void setElement(T element) {
        this.element = element;
    }

    public LinearNode<T> getNext() {
        return next;
    }

    public void setNext(LinearNode<T> next) {
        this.next = next;
    }
}

实现代码

public class LinkedStack<T> implements StackADT<T> {

    private int count;
    private LinearNode<T> top;

    public LinkedStack() {
        count = 0;
        top = null;
    }

    /**
     * 实现步骤:
     * 1、创建一个新结点,该结点含有一个引用,指向要放置到栈中的对象
     * 2、把新结点的next引用设置为指向当前栈顶(如果为空,那它就是null)
     * 3、把top引用设置为指向该新结点
     * 4、递增栈的元素计数
     *
     * @param element
     */
    @Override
    public void push(T element) {
        LinearNode<T> temp = new LinearNode<>(element);
        temp.setNext(top);
        top = temp;
        count++;
    }

    /**
     * 实现步骤:
     * 1、确保栈不为空
     * 2、设置一个临时引用等于栈顶元素
     * 3、设置top引用等于栈顶结点的next引用
     * 4、递减栈的元素计数
     *
     * @return
     */
    @Override
    public T pop() {
        if (isEmpty()) {
            throw new EmptyCollectionException("ArrayStack");
        }
        T result = top.getElement();
        top = top.getNext();
        count--;
        return result;
    }

    @Override
    public T peek() {
        return top.getElement();
    }

    @Override
    public boolean isEmpty() {
        if (count == 0) {
            return true;
        }
        return false;
    }

    @Override
    public int size() {
        return count;
    }

    @Override
    public String toString() {
        if (count == 0) {
            return "{}";
        } else {
            StringBuilder sb = new StringBuilder("{");
            LinearNode<T> current = top;
            for (int i = size() - 1; i >= 0; i--) {
                if (current.getElement() != null) {
                    if (i != 0) {
                        sb.append(current.getElement().toString() + ";");
                    } else {
                        sb.append(current.getElement().toString());
                    }
                }
                current = current.getNext();
            }
            int len = sb.length();
            return sb.append("}").toString();
        }
    }

}

测试代码

public class TestLinkStack {
    public static void main(String[] args) {
        LinkedStack<Integer> arrayStack = new LinkedStack<>();
        arrayStack.push(123);
        arrayStack.push(13);
        arrayStack.push(15);
        arrayStack.push(16);
        arrayStack.push(18);
        System.out.println(arrayStack);

        LinkedStack<Integer> invertStack = new LinkedStack<>();//反转
        int length = arrayStack.size();
        for (int i = 0; i <length; i++) {
            invertStack.push(arrayStack.pop());
        }
        System.out.println(invertStack);
        System.out.println(invertStack.size());
    }
}

运行结果

{18;16;15;13;123}
{123;13;15;16;18}
5

顺序栈、链表栈对比

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值