数据结构之队列

队列

队列概念

队列:只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有先进先出的特点。
入队列:进行插入操作的一端称为队尾。
出队列:进行删除操作的一端称为队头。

基本用法

 Queue<Integer> queue=new  LinkedList<>();
    	  queue.add(1);//插入元素
    	  queue.offer(2);///插入元素【常用】
    	  System.out.println(queue.element());//获取队头元素  1
    	  System.out.println(queue.peek());//获取队头元素   1【常用】
    	  System.out.println(queue.poll());//出元素   1  【常用】
    	  System.out.println(queue.remove());//出元素    2
    	  

在这里插入图片描述

双端队列

概念

双端队列(deque)是指允许两端都可以进行入队和出队操作的队列。

基本用法

 Deque<Integer>  queue2=new    LinkedList<>();
		 queue2.offer(1);//默认从队尾入队
		 queue2.offerFirst(2);
		 System.out.println(queue2.peek());
		 

在这里插入图片描述
🎈LinkedList,可以当做普通的队列,可以当做双端队列,可以当做双向链表,也可以当做栈。

用单链表实现队列

在这里插入图片描述

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

public class LiMyQueue {
     public Node head;
     public Node last;
     
     //尾插法
     public void offer(int val) {
    	 Node node= new Node(val);
    	 if(head==null) {
    		 head=node;
    		 last=node;
    	 }else {
    		 last.next=node;
    		 last=last.next;
    	 }
    	 
     }
     
     //出队
     public int poll() {
    	 if(isEmpty()) {
    		 throw new RuntimeException("队列为空");
    	 }
    	 int oldVal=head.val;
    	 this.head=head.next;
    	 return oldVal;
     }
     public boolean isEmpty() {
    	 return this.head==null;
     }
     
     public int peek() {
    	 if(isEmpty()) {
    		 throw new RuntimeException("队列为空");
    	 }
    	 return head.val;
     }
     
}

循环队列

如果使用数组实现队列。

循环队列判断是空还是满

使用usedSize

使用usedSize和数组长度进行比较,判断满或者空。

使用标志位

在这里插入图片描述

浪费一个空间

在这里插入图片描述

实现循环队列

//以下判空判满是使用浪费一个空间的方法

public class LiMyCircularQueue {
       public  int[] elem;
       public int front;//队头下标
       public int rear;//队尾下标
       public   LiMyCircularQueue(int k) {
    	   this.elem=new int[k];
       }
       
       //入队
       public boolean enQueue(int value) {
    	   if(isFull()) {
    		   return false;
    	   }
    	   this.elem[rear]=value;
    	   rear=(rear+1)%elem.length;
    	   return true;
       }
       
       //出队
       public boolean deQueue() {
    	   if(isEmpty()) {
    		   return false;
    	   }
    	   front=(front+1)%elem.length;
    	   return true;
       }
       
       //得到队头元素
       public int front() {
    	   if(isEmpty()) {
    		   return -1;
    	   }
    	   return elem[front];
       }
       
       //得到队尾元素
       public int rear() {
    	   if(isEmpty()) {
    		   return -1;
    	   }
    	   int index=-1;
    	   if(rear==0) {
    		   index=elem.length-1;
    	   }else {
    		   index=rear-1;
    	   }
    	   return elem[index];
       }
       
       
       
       //判空
       public boolean isEmpty() {
    	   return front==rear;
       }
       
       
       
       //判满
       public boolean isFull() {
    	   //rear的下一个是front说明满了
    	   if((rear+1)%elem.length==front ) {
    		   return true;
    	   }
    	   return false;
       }
}

习题

用队列实现栈

链接

在这里插入图片描述

入栈的时候,入到不为空的队列,刚开始都为空,指定入到一个队列。
出栈的时候,找到不为空的队列,出size-1个元素到另一个队列,剩下的这个元素就是出栈的元素。

 private Queue<Integer> qu1;
    private Queue<Integer> qu2;
    public MyStack() {
    qu1=new LinkedList<>();
    qu2=new LinkedList<>();
    }
    
    public void push(int x) {
       if(!qu1.isEmpty()){
           qu1.offer(x);
       }else if(!qu2.isEmpty()){
           qu2.offer(x);
       }else{
            qu1.offer(x);
       }
    }
    
    public int pop() {
        if(empty())   return -1;
        if(!qu1.isEmpty()){
            int size=qu1.size();
            for(int i=0;i<size-1;i++){
                int val=qu1.poll();
                qu2.offer(val);
            }
        return qu1.poll();
        }

        if(!qu2.isEmpty()){
            int size=qu2.size();
            for(int i=0;i<size-1;i++){
                int val=qu2.poll();
                qu1.offer(val);
            }
        return qu2.poll();
        }
        return -1;


    }
    
    public int top() {
        if(empty())   return -1;
        if(!qu1.isEmpty()){
            int val=-1;
            int size=qu1.size();
            for(int i=0;i<size;i++){
                val=qu1.poll();
                qu2.offer(val);
            }
        return val;
        }

        if(!qu2.isEmpty()){
            int val=-1;
            int size=qu2.size();
            for(int i=0;i<size;i++){
                 val=qu2.poll();
                qu1.offer(val);
            }
        return val;
        }
        return -1;
    }
    
    public boolean empty() {
        return qu1.isEmpty() && qu2.isEmpty();
    }

用栈实现队列

链接

入队的时候,统一入到第一个栈
出栈的时候,统一出第二个栈里面的元素,如果第二个栈为空,吧第一个栈的元素全部到过来,然后出栈顶元素

class MyQueue {
    public Stack<Integer> stack1;
    public Stack<Integer> stack2;

    public MyQueue() {
        stack1=new Stack<>();
        stack2=new Stack<>();

    }
    
    public void push(int x) {
        stack1.push(x);
    }
    
    public int pop() {
        if(empty())   return -1;
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
           
        }
        return  stack2.pop();
    }
    
    public int peek() {
         if(empty())   return -1;
        if(stack2.isEmpty()){
            while(!stack1.isEmpty()){
                stack2.push(stack1.pop());
            }
           
        }
        return  stack2.peek();
    }
    
    public boolean empty() {
        return stack1.isEmpty() &&   stack2.isEmpty();
    }
}

设计循环队列

链接

class MyCircularQueue {

    public int[] elem;
    public int front;//对头下标
    public int rear;//队尾下标
    public MyCircularQueue(int k){
        this.elem=new int[k+1];
    }

    //入队
    public boolean enQueue(int value){
        if(isFull())  return false;
	    this.elem[rear]=value;
	    rear=(rear+1) % elem.length;
        return true;
    }
    //出队
    public boolean deQueue(){
        if(isEmpty()){
            return false;
        }
        front=(front+1)%elem.length;
        return true;
    }

    //得到队头元素
    public int Front(){
        if(isEmpty()){
            return -1;
        }
        return elem[front];
    }
    //得到队尾元素
    public int Rear(){
        if(isEmpty()){
            return -1;
        }
        int index=-1;
        if(rear==0){
            index=elem.length-1;
        }else{
            index=rear-1;
        }
        return elem[index];
    }

    public boolean isFull(){
        //rear的下一个是front
        if((rear+1) % elem.length==front){
            return true;
        }
        return false;
    }
    public boolean isEmpty(){
        return front==rear;
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值