栈和队列(Java)

1.栈(Stack)
1.1栈的基本概念:
栈:一种特殊的线性表,其只允许在固定的一端插入和删除元素的操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵循的是后进先出(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/出栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈,出数据在栈顶。
1.2入栈与出栈示意图
1.2.1入栈示意图:
栈和队列(Java)_第1张图片
1.2.2出栈示意图:
栈和队列(Java)_第2张图片
1.3实现(栈)
1.3.1利用顺序表来实现栈(使用尾插操作表示“入栈”,使用尾删操作表示“出栈”,根据下标来获取元素的操作表示“取栈顶元素”操作)

//标准库中也有一个“Stack”这样的类,为了区别开,咱们别和标准库重合

public class MyStack {
     
    private int[] data=new int[100];
    private int size=0;

    //基本操作
    //1.入栈
    public void push(int val){
     
        if(size>=data.length){
     
            //在这里也可以进行扩容
            return;
        }
        data[size]=val;
        size++;
    }

    //2.出栈,返回值就是被出栈了的那个元素
    public Integer pop(){
     
        if(size==0){
     
            return null;
        }
        //栈顶元素就是最后一个元素
        int ret=data[size-1];
        size--;
        return ret;
    }

    //3.取栈顶元素
    public Integer peek(){
     
        if(size==0){
     
            return null;
        }
        return data[size-1];
    }
}

1.3.2:利用链表来实现栈(使用“头插操作”表示入栈,使用头删操作表示“出栈”,直接取头结点,表示取“栈顶元素”)

//使用链表来实现栈
class Node{
     
    int val;
    Node next;

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

public class MyStack2 {
     
    private Node head=null;

    //核心操作
    //1.入栈
    public void push(int val){
     
        Node newNode=new Node(val);
        //把新结点进行头插
        if(head==null){
     
            head=newNode;
            return;
        }
        newNode.next=head;
        head=newNode;
    }

    //出栈
    public Integer pop(){
     
        //进行头删
        if(head==null){
     
            return null;
        }
        if(head.next==null){
     
            int ret=head.val;
            head=null;
            return ret;
        }
        int ret=head.val;
        head=head.next;
        return ret;
    }

    //3.取栈顶元素
    public Integer peek(){
     
       if(head==null) {
     
           return null;
       }
       return head.val;
    }
}

``**2.队列**
2.1队列的基本概念
**队列**:只允许一端进行插入数据操作,在另外一端进行删除数据操作的特殊线性表,队列具有**先进先出**(First In First Out)
**入队列**:进行插入操作的一端称为队尾(Tail/Rear)
**出队列**:进行删除操作的一端称为队头(Head/Front)
2.2实现
2.2.1使用链表来实现队列(使用尾插表示入队列(插入一端的操作称为队尾),使用头删的操作表示出队列(进行删除的一端称为队头),直接获取头结点,就是取队首元素)

```java
//使用链表实现队列
public class MyQueue {
     
     static class Node{
     
        int val;
        Node next;

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

    //创建一个链表的头结点
    //为了方便的进行尾插
    private Node head=null;
     private Node tail=null;

     //队列的核心操作也是3个
    //1.入队列
    //表示插入成功或者插入失败
    //也是为了和标准库中的offer接口看起
    public boolean offer(int val){
     
        Node newNode=new Node(val);
        //插入到链表的尾部
        if(head==null){
     
            head=newNode;
            tail=newNode;
            return true;
        }
        tail.next=newNode;
        tail=tail.next;
        return true;
    }

    //2.出队列
    public Integer poll(){
     
        if(head==null){
     
            return null;
        }
        int ret=head.val;
        if(head.next==null){
     
            head=null;
            return ret;
        }
        head=head.next;
        return ret;
    }

    //取队首元素
    public Integer peek(){
     
        if(head==null){
     
            return null;
        }
        return head.val;
    }
  }

2.2.2使用顺序表来实现队列

//使用数组来实现队列
//就稍微复杂一点,单纯使用顺序表,势必会涉及头插
public class MyQueue2 {
     
    //队列的有效区间为[head,tail)
    private int [] data=new int [100];
    private int head=0;
    private  int tail=0;
    private int size=0;

    //核心操作
    //1.入队列
    public boolean offer(int val){
     
        if(size==data.length){
     
          //队列满了,此处可以实现扩容逻辑
          return false;
        }
        //把新元素放到tail对应的下标上
        data[tail]=val;
        //自增tail
        tail++;
        //一旦tail到达了数组的末尾,就让tail从头开始
        if(tail==data.length){
     
            tail=0;
        }
        //这个代码也可以写作
        tail=tail%data.length;
        //更新size的值
        size++;
        return true;
    }

    //2.出队列
    public Integer poll(){
     
        if(size==0){
     
            return null;
        }
        int ret=data[head];
        //更新head的位置
        head++;
        if(head==data.length){
     
            head=0;
        }
        size--;
        return ret;
    }

    //取队首元素
    public Integer peek(){
     
        if(size==0){
     
            return null;
        }
        return data[head];
    }
}

你可能感兴趣的:(队列,java)