栈和队列

Posted ssskkk

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了栈和队列相关的知识,希望对你有一定的参考价值。

栈:先进后出(底层用数组实现)

 只有一个开口,先进去的就到最底下,后进来的就在前面,要是拿出去的话,肯定是从开口端拿出去,
 所以说先进后出,后进先出。

数据结构:

技术分享图片

java实现栈(基于数组):

/**
 * 栈只有一个开口,先进去的就到最底下,后进来的就在前面,要是拿出去的话,肯定是从开口端拿出去,
 * 所以说先进后出,后进先出。
 */
public class MyStack {
    //底层实现是一个数组
    private long[] arr;
    /**
     * 最上层的一个指针 栈顶
     */
    private int top;
    /**
     * 默认的构造方法
     */
    public MyStack(){
        arr = new long[10];
        top=-1;
    }
    /**
     * 增加数据 先把指针加一
     * 然后指针指向最新的数据
     */
    public void push(int value){
        //top++是top先不自加,在语句完后自加。| ++top先自加 然后使用top的值
        arr[++top] = value;
    }
    
    /**
     * 移除数据 先把最顶层指针执行的数据return 然后指针减一
     */
    public long pop(){
        //--top 是先执行top=top-1,然后再使用top的值 | top-- 是先使用top的值 然后 在执行top=top-1
        return arr[top--];
    }
    
    public static void main(String[] args) {
        MyStack myStack = new MyStack();
        myStack.push(1);
        myStack.push(2);
        myStack.push(3);
        System.out.println(myStack.pop());
    }
}

main()方法中 3是最后push()进去 是最先pop()出来,先进后出,后进先出。

队列:先进先出(底层用数组实现)

队列有队头(front)和队尾(end),数据从队尾进入队列,从队头出队列,队头(front)指向队列的第一个数据,队尾(end)指向队列中的最后一个数据。

队列的数据结构

技术分享图片

java实现队列(基于数组)

package javaee.net.cn.tree.ch10;

public class MyQueue {
    //底层使用数组
    private long[] arr;
    //队头
    private int front;
    //队尾
    private int end;
    
    /**
     * 默认构造方法
     */
    public MyQueue(){
        arr = new long[10];
        front=0;
        end = -1;
    }
    /**
     * 添加数据 从队尾插入
     */
    public void insert(long value){
        arr[++end] = value;
    }
    /**
     * 删除数据,从队头删除
     */
    public long remove(){
        return arr[front++];
    }
    
    public static void main(String[] args) {
        MyQueue myQueue = new MyQueue();
        myQueue.insert(1L);
        myQueue.insert(2L);
        System.out.println(myQueue.remove());
    }
}

main()方法中 1是先insert()进去 也是先remove()出来,所以说 先进先出。

链表

上面的栈和队列都是以数组模拟实现,但是JDK中LinkedList底层是链表实现的,现在我们看看什么是链表

链表是由一个个的节点构成的,节点(Node)分为两个部分,第一个部分(data)保存或者显示关于节点的信息,另一个部分存储下一个节点的地址。

链表最后一个节点存储地址的部分指向空值。

节点Node:

/**
 * 连接点 相当于是车厢
 */
public class Node {
    //数据域 保存数据
    public long data;
    
    //指针域 保存下一个节点的引用
    public Node next;
    
    public Node(long value){
        this.data=value;
    }
}

而插入一个节点,对于单向链表,我们只提供在链表头插入,只需要将next指向原头节点,当前插入的节点设置为头节点即可。

    /**
     * 插入一个节点,在头结点进行插入
     */
    public void insertFirst(long value){
        Node node = new Node(value);
        node.next=first;
        first=node;
    }

删除一个节点,我们将该节点的上一个节点的next指向该节点的下一个节点。

如果被删除的是头结点,直接将头节点的下一个节点,赋值给头节点

    /**
     * 删除方法 根据数据域进行删除
     */
    public Node delete(long value){
        Node current = first;
        Node pre = null;
        while(current.data!=value){
            if(current.next==null){
                return null;
            }
            pre = current;
            current= current.next;
        }
        if(current == first){
            first = first.next;
        }else{
            pre.next=current.next;
        }
        return current;
    }

JDK中的LinkedList(底层用链表实现)

以上队列是以数组来模拟(比较简单),JDK API中的Queue队列底层是以链表来实现的。

LinkedList 类实现了Deque(双端队列)接口 并且具有

addFirst()  addLast()  getFirst() getLast() removeFirst() removeLast() 方法

使得LinkList可以作为 栈 队列 双向队列使用

至于LinkedList的实现原理,在这就不做多叙述了 大家可以参考API

以上是关于栈和队列的主要内容,如果未能解决你的问题,请参考以下文章

栈和队列基本操作

栈和队列

博客作业03--栈和队列

博客作业03--栈和队列

栈和队列知识点总结

栈和队列的面试题Java实现