数据结构(Java)——栈的实现总结

感谢Java软件结构与数据结构 John Lewis Joseph chase 著 金名译

基本的定义理解

  • 集合:集合是一个对象,它可以聚集和组织其他对象。
  • 数据类型:程序设计语言中一组值以及作用于这些数值上的各种操作。
  • 抽象数据类型:是一种在程序设计语言中尚未定义其值和操作的数据类型,他必须由编程人员定义。
  • 数据结构:是一种用于实现抽象数据类型的对象集。数据结构是计算机存储、组织数据的方式
  • 抽象:隐藏了操作和数据存储的基本实现,,以便简化集合的使用。
  • 栈的五种基本操作:

   1). push:添加一个元素到栈的顶端
   2).pop:从栈的前端一出一个元素
   3).peek:返回一个指向栈的前端元素的引用
   4)isEmpty:判断栈是否为空
   5)size:返回栈的元素数目

  • 继承定义:从已有类中派生出一个新类的过程。新类自动的含有初始类的部分或者全部的变量和方法。因此如果需要定制类,编程人员可以给派生类添加新的变量和方法或者修改继承来的变量和方法。
  • 多态定义:术语多态可以定义为具有多种形式。多态引用是一个引用变量它可以在不同的地方指向不同类型的对象,通过多态调用的某个方法,在每次调用的时候都可以发生变化。

栈的实现

1. 栈ADT

StackADT.java

package ds.java.ch03;
/** 
 * @author LbZhang
 * @version 创建时间:2015年11月14日 下午7:20:50 
 * @description 栈的抽象数据类型 接口
 */
public interface StackADT<T> {
    public void push(T elem);
    public T pop();
    public T peek();
    public boolean isEmpty();
    public int size();
    public String toString();

}

2. 栈的数组实现

ArrayStack.java

package ds.java.ch03;

import java.util.Arrays;

/**
 * @author LbZhang
 * @version 创建时间:2015年11月14日 下午7:23:53
 * @description 使用数组实现的栈 实现了自增长功能
 */
public class ArrayStack<T> implements StackADT<T> {

    private final int DEFAULT_CAPACITY = 100;
    private int top;// as a mark
    private T[] stack;

    /**
     * constructor method
     */
    public ArrayStack() {
        top = 0;
        // 未检验类型转换警告
        stack = (T[]) new Object[DEFAULT_CAPACITY];
        //注意泛型以及泛型数组不能被实例化
    }

    public ArrayStack(int init) {
        top = 0;
        // 未检验类型转换警告
        stack = (T[]) new Object[init];
        //注意泛型以及泛型数组不能被实例化
    }

    @Override
    public void push(T elem) {
        if(size()==stack.length){
            expandCapacity();
        }
        stack[top] = elem;;
        top++;//当前的栈顶是空的

    }

    /**
     * 栈的容量的扩展
     */
    private void expandCapacity() {
        stack = Arrays.copyOf(stack, stack.length*2);

    }

    @Override
    public T pop() throws EmptyCollectionException{
        if(isEmpty()){
            throw new EmptyCollectionException("stack");
        }
        top--;
        T result = stack[top];
        stack[top] = null;
        return result;
    }

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

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

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

    @Override
    public String toString() {
         StringBuilder  result = new StringBuilder();
         result.append("");
            for (int scan=0; scan < top; scan++)
                 result.append( stack[scan].toString() + "\n");

            return result.toString();
    }
}

3. 栈的链表实现

链表结点LinearNode.java

package ds.java.ch03.stackImpl;
/** 
 * @author LbZhang
 * @version 创建时间:2015年11月14日 下午8:26:10 
 * @description 链表结点类的定义
 *  其中含有两个引用
 *  一个是指向链表的下一个结点
 *  一个是指向本结点中存储的元素
 */
public class LinearNode<T> {

    private LinearNode<T> next;
    private T elem;

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

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


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

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

    public T getElem() {
        return elem;
    }

    public void setElem(T elem) {
        this.elem = elem;
    }


}

链表结点LinkedStack.java

package ds.java.ch03.stackImpl;

/**
 * @author LbZhang
 * @version 创建时间:2015年11月14日 下午8:22:06
 * @description 链栈: 由于使用的是链表的方式,因此我们这里无需用于存储集合元素的数组,只需要一个引用(引用指向链表的首结点)。
 *              此外我们维护了链表的元素计数.
 * 
 */
public class LinkedStack<T> implements StackADT<T> {

    private int count;
    // 指向栈顶的指针
    private LinearNode<T> top;

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

    /**
     * 创建一个新的结点,该结点含有一个引用,指向要放置到战中的对象 把新结点的next设置为top 把top引用设置指向当前新结点 递增栈的元素计数
     */
    @Override
    public void push(T elem) {
        // /结点的创建 和 引用声明
        LinearNode<T> temp = new LinearNode<T>(elem);
        temp.setNext(top);
        top = temp;
        count++;

    }

    @Override
    public T pop() throws EmptyCollectionException {
        if (isEmpty()) {
            throw new EmptyCollectionException("LinkedStack");
        }

        T result = top.getElem();
        top = top.getNext();
        count--;
        return result;
    }

    @Override
    public T peek() {
        if (isEmpty()) {
            throw new EmptyCollectionException("LinkedStack");
        }

        T result = top.getElem();
        return result;
    }

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

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

    @Override
    public String toString() {
        StringBuilder result = new StringBuilder();
        result.append("");
        LinearNode<T> temp = top;
        while(temp!=null){
            result.append(temp.getElem()+"\n");
            temp = temp.getNext();
        }
        return result.toString();
    }

}

4. 辅助类实现

EmptyCollectionException.java

package ds.java.ch03.stackImpl;
/** 
 * @author LbZhang
 * @version 创建时间:2015年11月14日 下午7:50:00 
 * @description 自定义异常类
 */
public class EmptyCollectionException extends RuntimeException {

    public EmptyCollectionException(String collection) {
        super("the " + collection + "is Empty!");
    }
}

5. 总结

栈是一种线性集合,其元素的添加和删除都是在同一端进行的。我们称栈是LIFO的方式处理的。
栈的案例应用:

  • 表达式的求解
  • 迷宫算法
posted @ 2015-11-14 19:02  snowwolf101  阅读(343)  评论(0编辑  收藏  举报