数据结构基础8:队列

前言:队列(Queue)是一种先进先出(FIFO)的线性表。特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作。在队列中插入一个队列元素称为入队,从队列中删除一个队列元素称为出队。因为队列只允许在一端插入,在另一端删除,所以只有最早进入队列的元素才能最先从队列中删除。

要实现队列,需要设置两个指针进行管理:一个是队头指针front,它指向队首元素;另一个是队尾指针rear,它指向下一个入队元素。

 

一、数组实现

当rear = arrayLength-1时,队列无法再插入新元素,但这时往往还有大量可用空间未被占用,这些空间是已经出队的队列元素曾经占用过得存储单元。所以实际应用中,我们为了使队列空间能重复使用,一旦rear指针增1 时超出了所分配的队列空间,就让它指向这片连续空间的起始位置。

这实际上是把队列空间想象成一个环形空间,环形空间中的存储单元循环使用,用这种方法管理的队列也就称为循环队列。

麻烦,需要的朋友可以自己去实现一下,我一般用链表实现的LinkQueue。

 

二、链表实现

同样,用front和rear分别表示队首和队尾元素。当且仅当队列为空时,front = null。

/*
 * 
 *  队列的链表实现
 */

public class LinkQueue 
{
   public Node front;//队首元素
   public Node rear;//队尾元素
   public int queueSzie = 0;
   
   
   //入队,把新节点插入队尾
   public void enQueue(Node newNode)
   {
	   if(queueSzie==0)
	   {
		   front = newNode;//队列为空
	   }
	   else 
	   {
		   rear.next = newNode;
	   }
	   
	   rear = newNode;//新节点为队尾元素
	   queueSzie++;
   }
   
  //出队,删除队首元素
   public void deQueue() 
   {
	   if(front == null)
		   System.out.println("Queue is null!");
	   
	   Node nextNode = front.next;//队首元素指向的下一个节点
	   
	   front = null;
	   
	   front = nextNode;
	   queueSzie--;
   }
	
  //查看队首元素的数据
   public int peek()
   {
	   return front.data;
   }
	
   //队列大小
   public int Size()
   {
	   return queueSzie;
   }
   
}

三、Java中使用Queue

Queue接口与List、Set同一级别,都是继承了Collection接口,remove、element、offer 、poll、peek 其实是属于Queue接口。

而LinkedList类实现了Queue接口,因此我们可以把LinkedList当成Queue来用。

1、LinkList接口的方法:

add        增加一个元索                     如果队列已满,则抛出一个IIIegaISlabEepeplian异常
remove   移除并返回队列头部的元素    如果队列为空,则抛出一个NoSuchElementException异常
element  返回队列头部的元素             如果队列为空,则抛出一个NoSuchElementException异常
offer       添加一个元素并返回true       如果队列已满,则返回false
poll         移除并返问队列头部的元素    如果队列为空,则返回null
peek       返回队列头部的元素             如果队列为空,则返回null
put         添加一个元素                      如果队列满,则阻塞
take        移除并返回队列头部的元素     如果队列为空,则阻塞

Queue接口窄化了对LinkedList的方法的访问权限(即在方法中的参数类型如果是Queue时,就完全只能访问Queue接口所定义的方法 了,而不能直接访问 LinkedList的非Queue的方法),以使得只有恰当的方法才可以使用。

2、使用举例:

import java.util.LinkedList;
import java.util.Queue;
 
public class Main {
    public static void main(String[] args) {
        //add()和remove()方法在失败的时候会抛出异常(不推荐)
        Queue queue = new LinkedList();
        //添加元素
        queue.offer("a");
        queue.offer("b");
        queue.offer("c");
        queue.offer("d");
        queue.offer("e");
        for(String q : queue){
            System.out.println(q);
        }
        System.out.println("===");
        System.out.println("poll="+queue.poll()); //返回第一个元素,并在队列中删除
        for(String q : queue){
            System.out.println(q);
        }
        System.out.println("===");
        System.out.println("element="+queue.element()); //返回第一个元素 
        for(String q : queue){
            System.out.println(q);
        }
        System.out.println("===");
        System.out.println("peek="+queue.peek()); //返回第一个元素 
        for(String q : queue){
            System.out.println(q);
        }
    }
}

输出结果:

数据结构基础8:队列_第1张图片

四、队列应用

常见的有电路布线和图元识别问题,有兴趣的可以去看下书。

用队列来记录本身已经编号而其相邻位置尚未编号的方格。

 

 

 

你可能感兴趣的:(数据结构与算法)