数据结构与算法_栈_02

题记

我们知道,在数组中,若知道数据项的下标,便可立即访问该数据项,或者通过顺序搜索数据项,访问到数组中的各个数据项。但是栈和队列不同,它们的访问是受限制的,即在特定时刻只有一个数据项可以被读取或者被删除。众所周知,栈是先进后出,只能访问栈顶的数据,队列是先进先出,只能访问头部数据。这里不再赘述。
栈的主要机制可以用数组来实现,也可以用链表来实现,
下面分别使用两种来实现栈基本操作:

/**
 * 栈 先进后出
 * 数组来实现栈的基本操作
 * @author fancy
 * @date 2018-12-05 09:31
 */
public class ArrayStack {

    //存取数据
    private int[] array;
    //栈大小
    private int size;
    //栈顶部数据下标
    private int topIndex;

    public ArrayStack(int size) {
        this.array = new int[size];
        this.size = size;
        //初始化为-1 表示空栈
        this.topIndex = -1;
    }

    /**
     * 压入数据
     * @author fancy
     * @param value
     */
    public void push (int value) {
        if (isFull()) {
            throw new OutOfMemoryError("空间已满!");
        }
        array[++topIndex] = value;
    }

    /**
     * 弹出栈顶数据/并且删除数据
     * @author fancy
     */
    public int pop () throws Exception {
        if (isEmpty()) {
            throw new Exception("栈为空");
        }
        if (topIndex > size) {
            throw new ArrayIndexOutOfBoundsException("下标越界");
        }
        int i = array[topIndex];
//        初始化顶部
        array[topIndex] = 0;
        topIndex --;
        return i;
    }

    /**
     * 返回栈顶部数据 - 不删除顶部数据
     * @return
     */
    public int peek () throws Exception {
        if (isEmpty()) {
            throw new Exception("栈为空");
        }
        if (topIndex > size) {
            throw new ArrayIndexOutOfBoundsException("下标越界");
        }
        return array[topIndex];
    }


    /**
     * 判断栈是否满的
     * @return
     */
    private boolean isFull () {
        if (topIndex == size) {
            return true;
        }
        return false;
    }

    /**
     * 判断栈是否是空的
     * @return
     */
    private boolean isEmpty () {
        if (topIndex == -1) {
            return true;
        }
        return false;
    }
}

/**
 * 栈 先进后出
 *  链表实现 栈的基本操作
 * @author fancy
 * @date 2018-12-05 11:02
 */
public class LinkedListStack {

    private MyLinkedList list;

    public LinkedListStack () {
        this.list = new MyLinkedList();

    }

    public int getSize() {
        return this.list.getSize();
    }

    public boolean isEmpty() {
        if (list.getSize() == 0) {
            return true;
        }
        return false;
    }

    /**
     * 压栈
     * @author fancy
     * @param value
     */
    public void push(int value) {
        list.set(list.getSize(), value);
    }

    /**
     * 弹栈
     * @author fancy
     * @return
     */
    public int pop() {
        return list.remove(list.getSize());
    }

    public int peek() {
        return list.get(list.getSize());
    }
}
/**
 * 单项链表 - 组成一个环形
 * 链表没有下标
 * @author fancy
 * @date 2018-12-05 11:03
 */
public class MyLinkedList{

    private Node currentNode;
    private int size;

    public MyLinkedList(){
        currentNode = new Node();
        size = 0;
    }

    // 获取链表中的元素个数
    public int getSize(){
        return size;
    }

    // 返回链表是否为空
    public boolean isEmpty(){
        return size == 0;
    }

    // 在链表的index(0-based)位置添加新的元素e
    // 在链表中不是一个常用的操作,练习用:)
    public void add(int index, int data){
        if(index < 0 || index > size){
            throw new IllegalArgumentException("Add failed. Illegal index.");
        }
        Node prev = currentNode;
        for(int i = 0 ; i < index ; i ++){
            prev = prev.getNext();
        }
        prev.setNext(new Node(data, prev.getNext()));;
        size ++;
    }

    // 获得链表的第index(0-based)个位置的元素
    // 在链表中不是一个常用的操作,练习用:)
    public int get(int index){
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("Get failed. Illegal index.");
        }
        Node cur = currentNode.getNext();
        for(int i = 0 ; i < index ; i ++){
            cur = cur.getNext();
        }
        return cur.getData();
    }

    // 修改链表的第index(0-based)个位置的元素为e
    // 在链表中不是一个常用的操作,练习用:)
    public void set(int index, int data){
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("Update failed. Illegal index.");
        }
        Node cur = currentNode.getNext();
        for(int i = 0 ; i < index ; i ++){
            cur = cur.getNext();
        }
        cur.setData(data);
        size ++;
    }

    // 查找链表中是否有元素e
    public boolean contains(int value){
        Node cur = currentNode.getNext();
        while(cur != null){
            if(cur.getData() == value){
                return true;
            }
            cur = cur.getNext();
        }
        return false;
    }

    // 从链表中删除index(0-based)位置的元素, 返回删除的元素
    // 在链表中不是一个常用的操作,练习用:)
    public int remove(int index){
        if(index < 0 || index >= size){
            throw new IllegalArgumentException("Remove failed. Index is illegal.");
        }
        Node prev = currentNode;
        for(int i = 0 ; i < index ; i ++){
            prev = prev.getNext();
        }
        Node retNode = prev.getNext();
        prev.setNext(retNode.getNext());
        retNode.setNext(null);
        size --;
        return retNode.getData();
    }
}

/**
 * 单向链表节点
 * @author fancy
 * @date 2018-12-05 11:34
 */
public class Node {

    private int data;
    //下个节点
    private Node next;

    public Node() {

    }

    public Node(int data) {
        this.data = data;
    }

    public Node(int data, Node next) {
        this.data = data;
        this.next = next;
    }

    public int getData() {
        return data;
    }

    public void setData(int data) {
        this.data = data;
    }

    public Node getNext() {
        return next;
    }

    public void setNext(Node next) {
        this.next = next;
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37955980/article/details/84839662