队列:先进先出(FIFO)
队列的存储表示有两种:一种是基于数组的存储表示,一种是基于链表的存储表示。基于数组的存储表示也叫做顺序队列,为了避免假溢出,需要使用出循环数组(环形的表)进行存储。
1.顺序队列
队列一开始rear=front=0,两个指针都在初始位置,此时进来元素,放入rear指针所指的位置,之后往前移一格,依次进行。
队头指针进1:front = (front+1) % maxSize
队尾指针进1:rear = (rear + 1) % maxSize
判断队列是否已满:(rear+1) % maxSize == front(也就是说,让rear指针指到front的前一个位置就认为队列已满)
在以上判断条件下面,实际上是空着一个位置的。如果不留这个位置,则必须使用rear%maxSize来判断队列是否已满,这样就和判断队列是否是空的条件rear==font混淆了,因此必须留一个空。由此,在循环队列中,最多只能放置maxSize-1个元素。
2.链式队列
用单链表表示的链式队列特别适合于数据元素比较大的情形,而且不存在队列满而产生溢出的情况。另外,假如程序中需要使用多个队列,与多个栈(栈也分为顺序栈和链式栈)的情形一样,最好使用链式队列,这样不会存在存储分配不合理的问题,也不需要进行存储的移动。
public class QueueNode { private int data; private QueueNode next; public QueueNode(int data){ this.data = data; } public int getData() { return data; } public void setData(int data) { this.data = data; } public QueueNode getNext() { return next; } public void setNext(QueueNode next) { this.next = next; }}
2)队列定义
/** * 链式队列 * */public class Queue{ QueueNode firstNode; QueueNode rearNode; int count; public Queue(){ firstNode = new QueueNode(1);//如何彻底使之泛型化? rearNode = firstNode; } //增加元素 public void EnQueue(int data){ QueueNode node = new QueueNode(data); rearNode.setNext(node);//往后添加 rearNode = rearNode.getNext(); count++; } //删除元素 public int DeQueue(){ if(!isEmpty()){//非空情况下 QueueNode deNode = firstNode.getNext(); firstNode.setNext(deNode.getNext()); count--; if(isEmpty()){ rearNode = firstNode; } return deNode.getData(); }else{ return -1; } } public boolean isEmpty(){ return count == 0; } //清空队列 public void makeEmpty(){ firstNode.setNext(null); rearNode = firstNode; count = 0; }}
可以解决的问题:杨辉三角问题,游程编码问题(一种压缩技术)
优先队列
每次从队列中取出的应该是具有最高优先权的元素。也称为优先权队列
优先级队列是0个或者多个元素的集合,每个元素都有一个优先权或者值。对于优先级队列,执行的操作主要有1)查找;2)插入;3)删除。
最小优先级队列:查找操作作用是用来搜索优先权最小的元素,删除操作的作用用来删除该元素;
最大优先级队列:查找操作作用是用来搜索优先权最大的元素,删除操作的作用用来删除该元素;
插入操作只是简单的把一个新元素加入到队列中去。(实际也可以插入后进行一次调整使元素按照优先级排列)
还有双端队列:可以在两端进行删除插入操作