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

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

运算限制:先进先出

基本概念:允许插入的一端称为队尾(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];
	}
}

牺牲一个存储单元法。

/**
  
* 

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

*

Description:

* @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

 

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