(二)栈和队列(Java实现)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zl_StepByStep/article/details/80075835
本文主要是数组和链表实现栈、链表实现队列。栈和队列的结构都比较简单,用链表实现时都是单链表实现的!

一、栈

    先进后出。先进来的元素保存在栈的最底部,新来的元素则在栈顶堆积,直到栈满为止;而取元素的时候,只能从栈顶取,直到栈空为止。栈有两种方法:压栈(push)和弹栈(pop)。

    数组和链表都可以实现。数组最好只实现固定栈(栈的容量数量固定),链表可以实现动态栈(因为进出栈时,永远只需要对链表的头操作)。


1.1、数组实现栈

package com.review07;

public class MyArrayStack {
    //存数据的数组
    private int [] data;
    //栈的最大长度
    private int size;
    //栈顶的位置
    private int top;

    //构造方法初始化栈
    public MyArrayStack(int size) {
        this.data = new int[size];
        this.size = size;
        this.top = -1;
    }

    //获取栈的长度
    public int getSize() {
        return size;
    }

    //获取栈顶
    public int getTop() {
        return top;
    }

    //判断是否为空栈,(空:true)
    public boolean isEmpty() {
        return top == -1;
    }

    //判断是否为满栈
    public boolean isFull() {
        return (top+1) == size;
    }

    //压栈操作
    public void push(int data) {
        if(isFull()) {
            try {
                throw new Exception("栈已满!");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }else {
            top ++;
            this.data[top] = data;
        }
    }

    //弹栈操作
    public int pop() throws Exception {
        if(isEmpty()) {
            System.out.println("栈是空的,无元素可以弹出!");
            throw new Exception("栈是空的,无元素可以弹出!");
        }else {
            top --;
            return this.data[top]; //返回新的栈顶元素
        }
    }

    //获取栈顶元素,但不弹栈
    public int getTopValue() {
        return this.data[getTop()];
    }

    //main方法测试
    public static void main(String[] args) {
        MyArrayStack myArrayStack = new MyArrayStack(10);
        myArrayStack.push(23);
        myArrayStack.push(4);
        myArrayStack.push(2);
        myArrayStack.push(5);
        myArrayStack.push(7);
        System.out.println("现在栈顶元素为:"+ myArrayStack.getTopValue());

        while(!myArrayStack.isEmpty()) {
            try {
                System.out.println(myArrayStack.getTopValue()+
                    "弹出栈顶元素后,新的栈顶元素是:"+myArrayStack.pop());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}


1.2、链表实现栈

package com.review07.linkedStack;

/**
 * 用链表实现栈
 */
public class MyLinkedStack {
    private Node header; //栈顶元素
    private int elementCount;//栈内元素个数
    private int size;//栈的大小

    /**
     * 构造函数,构造出一个空的栈
     */
    public MyLinkedStack() {
        this.header = null;
        this.elementCount = 0;
        this.size = 0;
    }

    /**
     * 通过构造函数,构造出一个自定义大小的栈
     */
    public MyLinkedStack(int size) {
        this.header = null;
        this.elementCount = 0;
        this.size = size;
    }

    //设置头结点
    public void setHeader(Node header) {
        this.header = header;
    }

    //判断栈是否已满
    public boolean isFull() {
        if(elementCount ==size) {
            return true;
        }
        return false;
    }
    //判断栈是否为空的
    public boolean isEmpty() {
        if(elementCount == 0) {
            return true;
        }
        return false;
    }

    //压栈
    public void push(Object value) {
        if(this.isFull()) {
            throw new RuntimeException("栈满了!");
        }
        //这里将原来的header作为参数传入,然后以新new出来的Node作为header
        header = new Node(value,header);
        elementCount ++;
    }

    //弹栈
    public Object pop() {
        if(this.isEmpty()) {
            throw new RuntimeException("栈空了,无法弹出元素");
        }
        Object obj = header.getElement();
        header = header.next;
        elementCount --;
        return obj;
    }

    //返回栈顶元素
    public Object getHeaderElement() {
        if (this.isEmpty()) {
            throw new RuntimeException("栈是空的");
        }
        return header.getElement();
    }

    //main方法测试
    public static void main(String[] args) {
        MyLinkedStack myArrayStack = new MyLinkedStack(10);
        myArrayStack.push(23);
        myArrayStack.push(4);
        myArrayStack.push(2);
        myArrayStack.push(5);
        myArrayStack.push(7);
        System.out.println("现在栈顶元素为:"+ myArrayStack.getHeaderElement());

        while(!myArrayStack.isEmpty()) {
            try {
                System.out.println(myArrayStack.getHeaderElement()+"弹出栈顶元素后,新的栈顶元素是:"+myArrayStack.pop());
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}



二、队列

先进先出

    队列每一次都是要先删除前面的元素,数组越是删除前面的元素效率越是低,所以这里就不再研究数组实现队列了。相反的是使用链表实现会更简单,效率会更高!另外队列的结构比较简单,只需要用单链表就够了,进队列时,需要记录队尾。

             


下面用链表实现队列:rear记录尾,front记录头

package com.review07.linkedQueue;

/**
 * 单链表实现的队列
 */
public class MyLinkedQueue {
    Node front;//队首指针
    Node rear; //队尾指针

    public MyLinkedQueue() {
        this.front = null;
        this.rear = null;
    }

    /**
     * 将一个对象追加到队列的尾部
     */
    public void enqueue(Object obj) {
        //如果队列是空的
        if(rear == null && front == null) {
            rear = new Node(obj);
            front = rear;
        } else {
            Node node = new Node(obj);
            rear.next = node;
            rear = rear.next;
        }
    }

    /**
     * 队首对象出队
     * @return 出队的对象,队列空时返回null
     */
    public Object dequeue() {
        //如果队列空
        if(front == null) {
            return null;
        }
        else if(front == rear && rear != null) { //队列里只有一个元素
            Node node = front;
            rear = null;
            front = null;
            return node.element;
        }
        Object obj = front.element;
        front = front.next;
        return obj;
    }

    //main测试
    public static void main(String[] args) {
        MyLinkedQueue myLinkedQueue = new MyLinkedQueue();
        myLinkedQueue.enqueue("张三");
        myLinkedQueue.enqueue("Tom");
        myLinkedQueue.enqueue("Jack");
        myLinkedQueue.enqueue("小米");

        while(myLinkedQueue.front != null) {
            System.out.println(myLinkedQueue.dequeue());
        }
    }
}



猜你喜欢

转载自blog.csdn.net/zl_StepByStep/article/details/80075835