小言_互联网的博客

queue(Array、LinkedList实现)、Double Ended Queue

353人阅读  评论(0)

Queue : A list or collection with the restriction that insertion can be performed at one end(rear) and deletion can be performed at other end(font).

Operations

  • Enqueue(x):add (store) an item to the queue.
  • Dequeue():remove (access) an item from the queue.
  • peek() :Gets the element at the front of the queue without removing it.
  • isfull():Checks if the queue is full.
  • isEmpty():Checks if the queue is empty.

In queue, we always dequeue (or access) data, pointed by front pointer and while enqueing (or storing) data in the queue we take help of rear pointer.
在front指针处取数据或出队;在rear指针处入队。

一、Implementation of Queue by Array

因为时Array,所以操作时间复杂度为常数或O(1)

public class MyQueue {
 
	private int[] queArray;
	
	private int maxSize;//队列总大小
	
	private int front;
	private int rear;
	
	public MyQueue(int size)
	{
	  queArray=new int[size];
	  front=rear=-1;
	}
    public boolean isEmpty() {
    //为空情况有两种 ①未放过元素  ②只有一个,出队
     if(front==-1&&rear==-1)
         return true;
     return false;
	}
  public boolean isFull() {
      if(rear==queArray.length-1)
           return false;
		return true;
	}
public void Enqueue(int value) {
		if(isFull()) {
			return;
		}else if(isEmpty()){ 
		    front=rear=0;
		}else{
			rear++;	
		}
		 queArray[rear]=value;
	}
public int Dequeue() {
        int result=Integer.MAX_VALUE;
		if(isEmpty()){
		    return;
		}else if(front==rear){ //只有一个元素
		   result=queArray[front];
		   front=rear=-1;
		   
		}else{
		  result=queArray[front];
		  front++;
		} 
		return result;	
	}

但是,上面这种写法存在一个问题: 若此时要Enqueue(x),则根据上面代码执行isFull()时,会rear==queArray.length-1,从而无法插入数据。实际上queArray中索引0、1是空的,从而造成了空间浪费。如下图:

解决方法是用循环队列:

public class MyQueue {
 
	private int[] queArray;
	
	private int maxSize;//队列总大小
	
	private int front;
	private int rear;
	
	public MyQueue(int size)
	{
	  queArray=new int[size];
	  front=rear=-1;
	}
	
    public boolean isEmpty() {
     if(front==-1&&rear==-1)
         return true;
     return false;
	}
  public boolean isFull() {
  //比如front=0,rear=9 此时就是满的状态 (9+1)%10==0
      if((rear+1)%queArray.length==front)
           return false;
		return true;
	}
public void Enqueue(int value) {
		if(isFull()) {
			return;
		}else if(isEmpty()){ 
		    front=rear=0;
		}else{
//比如此时front=2,rear=9,则rear=(9+1)%10=0,则应存放在0号位置
			rear=(rear+1)%queArray.length
		}
		 queArray[rear]=value;
	}
public int Dequeue() {
        int result=Integer.MAX_VALUE;
		if(isEmpty()){
		    return;
		}else if(front==rear){ //只有一个元素
		   result=queArray[front];
		   front=rear=-1;
		   
		}else{
		  result=queArray[front];
	//比如front=9,rear=2,下一个则为()9+1)%10==0
		  front=(front+1)%queArray.length
		} 
		return result;	
	}

二、Implementation of Queue by Linked List

Array实现存在的问题:

  • 在队列初始化时,需要先指定队列数组大小。若满,则要创建更大的数组并且把数据复制过去。这个操作O(N)
  • 可能我们在初始化时指定了maxSize,但很多时候我们并不会用满,从而造成浪费。“unused memery”

解决方案:用链表
Linked list are collections of entities that we call Nodes.

cost of Insert/Removeal

  • at head:O(1)
  • at tail:O(N)
public class Node {
   int data;
   Node next;
}
public class MyQueue {
    private Node front=null;
    private Node rear=null;
  
    public boolean isEmpty() {
    //为空情况有两种 ①未放过元素  ②只有一个,出队
     if(front==null&&rear==null)
         return true;
     return false;
	}
 
public void Enqueue(int value) {
        //创建新节点
        Node tmp=new Node(value);
   
        //判断链表是否为空
		 if(isEmpty())
		   { front=rear=tmp;}
		   
		rear.next=tmp;
		rear=tmp;
		
	}

Dequeue (Double Ended Queue)

In this insertion and deletion can be performed both end.

用循环队列实现:


Deque can be classified as follows:

  • Input Restricted Queue:delete can be performed at both end;Insert at one end
  • Onput Restricted Queue:Insert can be performed at both end;deleteat one end

    We can also implement stacks and queues using deque.

参考:https://www.youtube.com/watch?v=okr-XE8yTO8
https://www.youtube.com/watch?v=A5_XdiK4J8A


转载:https://blog.csdn.net/jiangshangchunjiezi/article/details/105300842
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场