【数据结构与算法02】队列

本文详细介绍了队列的数据结构特性,包括其定义、运算限制和基本概念。重点讲述了队列的创建、判空、入队、出队和读队头数据等基本运算,并详细讨论了顺序队列(特别是循环队列)的设计,包括添加标识法和牺牲存储单元法解决队空队满判断问题。同时提到了链队列的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义:只允许在表的一端插入数据,而在表的另一端访问数据。根据存储方式可分为顺序队列链队列

运算限制:先进先出

基本概念:允许插入的一端称为队尾(rear),允许访问的一端称为队头(front)。

基本运算:

1::创建一个空的队列。

2:判空。

3:入队。添加到队尾,修改队尾指针。

4:出队。删除队头,修改队头指针。

5:读队头数据。

顺序队列说明:

利用一组地址连续的存储单元存放队列中的元素。为了降低运算的复杂度,元素入队时只修改队尾指针,元素出队时只修改队头指针,由于顺序队列的存储空间容量是提前设定的,所以队尾指针会有一个上限值,当队尾指针达到该上限时,就不能再向队尾添加元素,而应该从队头前被删除的地址添加,所以顺序队列通常被设计为环状结构,指针通过整除取余运算实现,这种队列称为循环队列。在队列空和队列满的时候,循环队列的队头和队尾指向相同的指针,无法判断是队空还是对满。针对这个情况有两个处理方式,一,添加一个标识用来区分队空或队满。二,牺牲一个存储单元,约定队尾的下一个位置是队头时为满,队尾等于队头是为空。

下面看一下两种的实现。

添加标识法。

public class RoundQueue implements Queue{
	
	private Integer[] array;
	
	private int size ;//循环队列的存储空间
	
	private int front ;//对头
	
	private int rear ;//对尾
	
	private int length ;//数组中元素的个数,=0时空,=size时满
	
	public RoundQueue(int initSize){
		this.size = initSize;
		array = new Integer[initSize];
		front = 0 ;
		rear = 0 ;
		length = 0 ;
	}
	
	@Override
	public boolean isEmpty() {
		return (length == 0);
	}

	@Override
	public boolean isFull() {
		return (length == size) ;
	}

	//入队时,判队满,修改队尾
	@Override
	public void enterQueue(int value) {
		if(isFull()) throw new ArrayIndexOutOfBoundsException(size);
		//队尾赋值
		array[rear] = value ;
		//队尾指向下一个位置
		rear = (rear + 1) % size ;
		//元素个数加1
		length++ ;
	}

	//出队时,判对空,修改对头
	@Override
	public Integer deleteQueue() {
		if(isEmpty()) return null;
		//取队头值
		int num = array[front] ;
		//队头值置空
		array[front] = null ;
		//队头指针指向下一个位置
		front = (front + 1) % size ;
		//元素个数-1
		length-- ;
		return num;
	}

	//查看队头
	@Override
	public Integer frontQueue() {
		return isEmpty()?null:array[front];
	}
}

牺牲一个存储单元法。

/**
  
* <p>Title: RoundQueueInsteadOne
* 数组长度不可变,初始化长度必须大于1,实际应用中长度不大于1的话也不需要用到队列</p>
  
* <p>Description: </p>  

* @author 未知神秘人物  

* @date 2019年3月6日  

*/
public class RoundQueueInsteadOne implements Queue{
	
	private Integer[] array;
	
	private int size ;//循环队列的存储空间
	
	private int front ;//对头
	
	private int rear ;//对尾
	
	public RoundQueueInsteadOne(int initSize){
		this.size = initSize;
		array = new Integer[initSize];
		front = 0 ;
		rear = 0 ;
	}
	
	@Override
	public boolean isEmpty() {
		return (front == rear);
	}

	@Override
	public boolean isFull() {
		return (((rear + 1) % size) == front) ;
	}

	//入队时,判队满,修改队尾
	@Override
	public void enterQueue(int value) {
		if(isFull()) throw new ArrayIndexOutOfBoundsException(size);
		array[rear] = value ;
		rear = (rear + 1) % size ;
	}

	//出队时,判对空,修改对头
	@Override
	public Integer deleteQueue() {
		if(isEmpty()) return null;
		int num = array[front] ;
		array[front] = null ;
		front = (front + 1) % size ;
		return num;
	}

	//查看队头
	@Override
	public Integer frontQueue() {
		return isEmpty()?null:array[front];
	}

}

链队列实现

public class LinkQueue implements Queue {
	
	private Link base;
	private Link front;
	private Link rear;

	static class Link{
		Integer data;
		Link next ;
	}

	@Override
	public void enterQueue(int value) {
		Link link = new Link();
		link.data = value ;
		if(isEmpty()){
			base = link;
			rear = base;
			front = base;
			return ;
		}
		rear.next = link;
		rear = rear.next ;
	}

	@Override
	public Integer deleteQueue() {
		if(isEmpty()){
			return null ;
		}
		int num = front.data;
		front = front.next;
		return num;
	}

	@Override
	public Integer frontQueue() {
		return isEmpty()?null:front.data;
	}

	@Override
	public boolean isEmpty() {
		
		return (base==null || front==null);
	}

	//没有了数组的长度限制,不需要判满
	@Override
	public boolean isFull() {
		return false;
	}
}

测试结果

public class Test {

	public static void main(String[] args) {
		RoundQueueInsteadOne roundQueue = new RoundQueueInsteadOne(2);
		System.out.println("roundQueue");
		System.out.println("isEmpty:"+roundQueue.isEmpty());
		System.out.println("isFull:"+roundQueue.isFull());
		roundQueue.enterQueue(111);
		System.out.println("deleteQueue:"+roundQueue.deleteQueue());
		System.out.println("frontQueue:"+roundQueue.frontQueue());
		
		RoundQueue rQueue = new RoundQueue(1);
		System.out.println("rQueue");
		System.out.println("isEmpty:"+rQueue.isEmpty());
		System.out.println("isFull"+rQueue.isFull());
		rQueue.enterQueue(111);
		System.out.println("deleteQueue:"+rQueue.deleteQueue());
		System.out.println("frontQueue:"+rQueue.frontQueue());
		
		LinkQueue queue = new LinkQueue();
		System.out.println("LinkQueue");
		System.out.println("isEmpty:"+queue.isEmpty());
		System.out.println("frontQueue:"+queue.frontQueue());
		System.out.println("deleteQueue:"+queue.deleteQueue());
		queue.enterQueue(111);
		queue.enterQueue(111);
		queue.enterQueue(111);
		System.out.println("isEmpty:"+queue.isEmpty());
		System.out.println("frontQueue:"+queue.frontQueue());
		System.out.println("deleteQueue:"+queue.deleteQueue());
		System.out.println("deleteQueue:"+queue.deleteQueue());
		System.out.println("deleteQueue:"+queue.deleteQueue());
		System.out.println("deleteQueue:"+queue.deleteQueue());
		
	}
}
roundQueue
isEmpty:true
isFull:false
deleteQueue:111
frontQueue:null
rQueue
isEmpty:true
isFullfalse
deleteQueue:111
frontQueue:null
LinkQueue
isEmpty:true
frontQueue:null
deleteQueue:null
isEmpty:false
frontQueue:111
deleteQueue:111
deleteQueue:111
deleteQueue:111
deleteQueue:null

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值