数据结构(二)——栈和队列的基本操作

前言

总体来说,栈和队列也是线性结构的一种,至于什么是栈,什么是队列,这里不会介绍,因为这玩意太基础。这里就不总结了,只是说一下,这里的栈和队列的底层实现其实有数组和链表的两种实现方式。

栈的基本操作

这里采用链表的实现方式,一个链表节点作为栈顶,一个链表节点作为栈底

基本数据结构如下所示:

/**
 * autor:liman
 * createtime:2020/2/5
 * comment: 栈,自己的栈操作,底层采用链表的数据结构
 */
public class MyStack {

    private ListNode stackTop;
    private ListNode stackBottom;

    public MyStack(ListNode stackTop,ListNode stackBottom){
        this.stackTop = stackTop;
        this.stackBottom = stackBottom;
	}
}

相关的入栈,出栈等操作

/**
 * 入栈操作
 * @param stack
 * @param value
 * 这个就好比在top头插入一个节点
 */
public static void pushStack(MyStack stack,int value){
    ListNode node = new ListNode(value);
    node.next = stack.stackTop;
    stack.stackTop=node;
}

/**
 * 遍历操作
 * @param stack
 * 遍历,利用stackTop进行走链的操作
 */
public static void traverse(MyStack stack){
    ListNode stackTop = stack.stackTop;
    while(stackTop!=stack.stackBottom){
        System.out.print(stackTop.value +" ");
        stackTop = stackTop.next;
    }
    System.out.println();
}

/**
 * 栈的判空操作
 * @param stack
 * @return
 * 
 */
public static boolean isEmpty(MyStack stack){
    if(stack.stackTop == stack.stackBottom){
        return true;
    }else{
        return false;
    }
}

/**
 * 出栈
 * @param stack
 * 在栈非空的情况下,相当于删除头节点。
 */
public static void popStack(MyStack stack){
    if(!isEmpty(stack)){
        ListNode stackTop = stack.stackTop;
        stack.stackTop = stackTop.next;
        System.out.println(stackTop.value);
    }
}

/**
 * 清空栈中的元素
 * @param stack
 * 这个够简单了,其余的节点会被JVM自动回收
 */
public static void clearStack(MyStack stack){
    stack.stackTop = null;
    stack.stackBottom = stack.stackTop;
}

队列的基本操作

栈的基本操作底层是基于链表实现的,这里的队列采用数组的方式实现。至于这个循环队列的底层图解,这个还是百度吧

public class MyQueue {

    public int[] arrays;
    public int front;   //指向的是第一个有效的元素
    public int rear;    //指向的是最后一个有效元素的下一个元素

    public MyQueue(int[] arrays, int front, int rear) {
        this.arrays = arrays;
        this.front = front;
        this.rear = rear;
    }
}

这里需要注意一下rear的指向,这个指向的是数组中最右一个有效元素的下一个元素,这个存储空间是个无效的元素

/**
 * 判断队列是否是满的
 * (queue.rear+1)%queue.length == queue.front,则表示队列已满
 * @param queue
 * @return
 */
public static boolean isFull(MyQueue queue) {
    if ((queue.rear + 1) % queue.arrays.length == queue.front) {
        return true;
    } else {
        return false;
    }
}

/**
 * 判断队列是否是空
 * queue.rear == queue.front则表示队列为空,这是最初始的状态
 * @param queue
 * @return
 */
public static boolean isEmpty(MyQueue queue) {
    if (queue.rear == queue.front) {
        return true;
    } else {
        return false;
    }
}

/**
 * 入队操作
 * 即操作队尾,将元素放到rear所指向的空间,然后rear前移 【(rear+1)%queue.length】
 * @param queue
 * @param value
 */
public static void enQueue(MyQueue queue, int value) {
    if (!isFull(queue)) {
        queue.arrays[queue.rear] = value;
        queue.rear = (queue.rear + 1) % queue.arrays.length;
    }
}

/**
 * 遍历操作
 *
 * @param queue
 */
public static void traverse(MyQueue queue) {
    int i = queue.front;
    while (i != queue.rear) {
        System.out.println(queue.arrays[i]);
        i = (i + 1) % queue.arrays.length;
    }
}

/**
 * 出队操作
 * 操作对头指针,front。之后front前移【(front+1)%queue.length】
 */
public static void outQueue(MyQueue queue) {
    if (!isEmpty(queue)) {
        int value = queue.arrays[queue.front];
        System.out.println(value);
        queue.front = (queue.front + 1) % queue.arrays.length;
    }
}

利用两个栈实现一个队列

思路:一个栈承接如对列的元素,在出队列之前,将第一个栈中的元素出栈,然后将元素入栈到第二个栈中即可,出队列即为从第二个栈中弹出元素。这里用Java底层的集合Stack来完成这个需求

public class DoubleStack2Queue {

    public Stack<Integer> stackPush;	//用于入队列的栈
    public Stack<Integer> stackPop;		//用于出队列的栈

    public DoubleStack2Queue(Stack<Integer> stackPush, Stack<Integer> stackPop) {
        this.stackPush = stackPush;
        this.stackPop = stackPop;
    }

    /**
     * 入队列。
     */
    public void add(int value){
        stackPush.push(value);
    }

    /**
     * 出队列的操作
     * @return
     */
    public int poll(){
        if(stackPop.isEmpty() && stackPush.isEmpty()){//队列为空
            throw new RuntimeException("队列为空");
        }else if(stackPop.isEmpty()){
            while(!stackPush.isEmpty()){//一股脑的直接将入队列的栈里面的所有元素放到出队列的栈中。
                stackPop.push(stackPush.pop());
            }
        }
        return stackPop.pop();
    }

    /**
     * 只是单纯的读取栈顶的元素
     * @return
     */
    public int peek(){
        if(stackPop.isEmpty() && stackPush.isEmpty()){//队列为空
            throw new RuntimeException("队列为空");
        }else if(stackPop.isEmpty()){
            while(!stackPush.isEmpty()){
                stackPop.push(stackPush.pop());
            }
        }
        return stackPop.peek();
    }
}

总结

是不是太easy了,都不想总结了。

发布了129 篇原创文章 · 获赞 37 · 访问量 9万+

猜你喜欢

转载自blog.csdn.net/liman65727/article/details/104201102