队列 (queue) ,基本数据结构之一,属于FIFO(先进先出)数据结构。队列只允许在前端 (HEAD) 进行入队(插入)操作,只允许在后端 (TAIL) 进行出队(删除)操作。
单队列可以使用链表来实现,实现非常简单,队列的长度也没有限制,但是插入和读取的时间代价较高。
循环队列可以使用数组来实现,因此操作起来很快,但是长度一般固定。但是可以通过设计一个扩大容量的方法来使其长度可变。
在后面给出的代码是基于数组的循环队列实现。
另外,有一种所谓的优先队列,实际上是依靠堆的结构来实现的,在以后练习到堆的时候会再提及。
简述循环队列实现原理:利用两个下标来确定队列范围:head 与 tail. 队列的默认构造器将使构造长度为DEFAULT_CAPACITY=10的队列,带整数参数的构造器将构造相应长度的队列。
队列另外有两个属性size和capacity,size表明队列中的元素个数,capacity表明当前队列的容量(可容纳元素个数)。
每当有元素入队时,size加一,每当有元素退队时,size减一。
因此可以简单通过size==0和size==capacity来判断isEmpty和isFull.
入队操作:当队列不为满的时候,在下标为tail的位置插入元素,自增size,调整tail的值: if(++tail==queue.length){tail=0;}
退队操作:当队列不空的时候,记录头元素的值,自减size,调整head的值: if(++head==queue.length){head=0;},返回头元素的值。
扩容方法 enlarge():当调用该方法时,将capacity*=2,容量增加一倍,然后创建新的数组,再将旧数组中的值复制到新数组中,在新数组中的位置将从0位置开始向后排列,具体实现看代码。
java代码:
[java] view plain copy
public class MyQueue{
public int size=0,head=0,tail=0;
private final int DEFAULT_CAPACITY=10;
private int capacity;
private int[] queue;
public MyQueue(){
queue=new int[DEFAULT_CAPACITY];
capacity=DEFAULT_CAPACITY;
}
public MyQueue(int capacity){
queue=new int[capacity];
this.capacity=capacity;
}
public void enqueue(int element){
if(!isFull()){
queue[tail]=element;
size++;
if(++tail==queue.length){
tail=0;
}
}
else{
System.out.println("Queue is full, use enlarge() method to enlarge.");
}
}
public int dequeue(){
if(!isEmpty()){
int x=queue[head];
size--;
if(++head==queue.length){
head=0;
}
return x;
}
else{
System.out.println("Queue is empty, cannot dequeue!");
return Integer.MIN_VALUE;
}
}
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
public boolean isFull(){
return size==capacity;
}
public void enlarge(){
capacity*=2;
int[] newQueue=new int[capacity];
int count=0,index=head;
while(++count<=size){
newQueue[count]=queue[index];
count++;
if(++index==queue.length){
index=0;
}
}
queue=newQueue;
head=0;
tail=size;
}
public String toString(){
String str="";
if(isEmpty())
return "This is an empty stack";
else{
str+="[";
int index=head,count=0;
while(++count<=size()){
str+=" "+queue[index];
if(++index==queue.length){
index=0;
}
}
str+=" ]";
}
return str;
}
public int getCapacity(){
return capacity;
}
}
单队列可以使用链表来实现,实现非常简单,队列的长度也没有限制,但是插入和读取的时间代价较高。
循环队列可以使用数组来实现,因此操作起来很快,但是长度一般固定。但是可以通过设计一个扩大容量的方法来使其长度可变。
在后面给出的代码是基于数组的循环队列实现。
另外,有一种所谓的优先队列,实际上是依靠堆的结构来实现的,在以后练习到堆的时候会再提及。
简述循环队列实现原理:利用两个下标来确定队列范围:head 与 tail. 队列的默认构造器将使构造长度为DEFAULT_CAPACITY=10的队列,带整数参数的构造器将构造相应长度的队列。
队列另外有两个属性size和capacity,size表明队列中的元素个数,capacity表明当前队列的容量(可容纳元素个数)。
每当有元素入队时,size加一,每当有元素退队时,size减一。
因此可以简单通过size==0和size==capacity来判断isEmpty和isFull.
入队操作:当队列不为满的时候,在下标为tail的位置插入元素,自增size,调整tail的值: if(++tail==queue.length){tail=0;}
退队操作:当队列不空的时候,记录头元素的值,自减size,调整head的值: if(++head==queue.length){head=0;},返回头元素的值。
扩容方法 enlarge():当调用该方法时,将capacity*=2,容量增加一倍,然后创建新的数组,再将旧数组中的值复制到新数组中,在新数组中的位置将从0位置开始向后排列,具体实现看代码。
java代码:
[java] view plain copy
public class MyQueue{
public int size=0,head=0,tail=0;
private final int DEFAULT_CAPACITY=10;
private int capacity;
private int[] queue;
public MyQueue(){
queue=new int[DEFAULT_CAPACITY];
capacity=DEFAULT_CAPACITY;
}
public MyQueue(int capacity){
queue=new int[capacity];
this.capacity=capacity;
}
public void enqueue(int element){
if(!isFull()){
queue[tail]=element;
size++;
if(++tail==queue.length){
tail=0;
}
}
else{
System.out.println("Queue is full, use enlarge() method to enlarge.");
}
}
public int dequeue(){
if(!isEmpty()){
int x=queue[head];
size--;
if(++head==queue.length){
head=0;
}
return x;
}
else{
System.out.println("Queue is empty, cannot dequeue!");
return Integer.MIN_VALUE;
}
}
public int size(){
return size;
}
public boolean isEmpty(){
return size==0;
}
public boolean isFull(){
return size==capacity;
}
public void enlarge(){
capacity*=2;
int[] newQueue=new int[capacity];
int count=0,index=head;
while(++count<=size){
newQueue[count]=queue[index];
count++;
if(++index==queue.length){
index=0;
}
}
queue=newQueue;
head=0;
tail=size;
}
public String toString(){
String str="";
if(isEmpty())
return "This is an empty stack";
else{
str+="[";
int index=head,count=0;
while(++count<=size()){
str+=" "+queue[index];
if(++index==queue.length){
index=0;
}
}
str+=" ]";
}
return str;
}
public int getCapacity(){
return capacity;
}
}