队列
让我们先了解一下队列的概念:队列是一种先进先出的线性表。它只允许在表的前端(front)进行删除工作,在表的后端(rear)进行插入工作,进行插入操作的一端称作队尾,进行删除操作的一端称作队头。队列中没有元称素作空队列。
java 实现循环队列
1 . 数组 elem 存储队列元素。
front 和 rear 分别表示队头和队尾。usedSize表示存储的有效位的个数。
allSize表示数组的长度。
数组仅存储 allSize - 1 个元素,还有一个空间被浪费。
循环队列不能用rear = rear + 1指向下一个元素,会发生越界,而要用this.rear = (this.rear+1) % this.allSize。
class QueueLink{
int elem[];
int front;//对头
int rear;//对尾
int usedSize;//有效数字个数。
int allSize = 10;
public QueueLink(){
this(10);
}
public QueueLink(int size){
this.elem = new int[size];
this.front = 0;
this.rear = 0;
}
2 . 循环队列的基本操作。
a . 判断队列是否为满。
public boolean isFull(){
return (this.rear+1) % this.allSize == this.front;
}
b . 入队。
public void push(int val){
//判断是否为满。
if(isFull()){
return;
}
this.elem[this.rear] = val;
this.rear = (this.rear+1) % this.allSize;
this.usedSize++;
}
c . 判断队列是否为空。
![](https://i-blog.csdnimg.cn/blog_migrate/e2b928858a748b36a0e81a38c81776bc.png)
public boolean isEmpty(){
return this.front == this.rear;
}
d . 出队。
public void pop(){
if(isEmpty()){
return;
}
this.elem[this.front] = -1;
this.front = (this.front+1)%this.allSize;
this.usedSize--;
}
e . 得到队头元素。
public int getTop(){
if(isEmpty()){
return -1;
}
return this.elem[this.front];
}
f . 输出队列元素。
public void show(){
for(int i = this.front; i < this.rear; i = (i+1) % this.allSize){
System.out.print(this.elem[i]+" ");
}
System.out.println();
}
3.测试结果
public static void main(String[] args) {
QueueLink q1 = new QueueLink();
for(int i = 0;i < 10;i++){
q1.push(i);
}
System.out.print("s:");
q1.show();
q1.pop();
System.out.println("=====出队后=====");
System.out.print("s:");
q1.show();
System.out.println("队顶元素:"+q1.getTop());
}
![](https://i-blog.csdnimg.cn/blog_migrate/b8aa9a0269e1741fbc96b3ce847a8c5f.png)
java实现链式队列
链式队列就是用链表实现队列,在链表头部表示队头,链表尾部表示对尾,采用尾插法就符合了队列在尾部插入的特点,在头部删除,这样就可以实现了先进先出的特点。为了提高插入的效率,用一个引用来表示存储的队尾节点,否则每次入队都要遍历整个链表。
1.链式队列的定义
class Queue{
class Entry{
int data;
Entry next;
public Entry(){
this.data = -1;
this.next = null;
}
public Entry(int data){
this.data = data;
this.next = null;
}
}
private Entry front = null;
private Entry rear = null;
private int usedSize = 0;//存储队列的长度。
2.链式队列的基本操作
a.队列是否为空
public boolean isEmpty(){
return usedSize == 0;
}
b.入队————尾插法
public void insert(int val){
Entry entry = new Entry(val);
if(this.usedSize == 0){
rear = entry;
front = rear;
}else{
rear.next = entry;
rear = entry;
}
this.usedSize++;
}
c.出队
public int pop(){
if(this.usedSize == 0){
return -1;
}
int num = front.data;
front = front.next;
this.usedSize--;
return num;
}
d.得到队头元素
public int getTop(){
if(isEmpty()){
return -1;
}
return front.data;
}
e.输出队列元素
public void show(){
Entry cur = front;
while(cur != null){
System.out.print(cur.data +" ");
cur = cur.next;
}
System.out.println();
}
3.测试结果
public static void main(String[] args) {
Queue q1 = new Queue();
q1.insert(1);
q1.insert(2);
q1.insert(3);
q1.insert(4);
q1.show();
System.out.println("对头元素:"+q1.getTop());
System.out.println(q1.pop());
System.out.println("对头元素:"+q1.getTop());
q1.show();
}
优先级队列
按照优先级存储数据。
在每个节点多了一个寻出优先级的域,数字越小优先级越高,优先级高的数据存储在前面。
1.队列的定义
class PrioLink1{
class Entry{
int data;
int prio;//优先级
Entry next;
public Entry(){
this.data = -1;
this.prio = -1;
this.next = null;
}
public Entry(int data,int prio){
this.data = data;
this.prio = prio;
this.next = null;
}
}
private Entry head = null;
public PrioLink1(){
this.head = new Entry();
}
}
2.队列的基本操作
a.入队——按照优先级顺序入队,优先级高的插在优先级低的前面。
![](https://i-blog.csdnimg.cn/blog_migrate/2bbfb5f442fecc013644026f3c54fb67.png)
public void insert(int data,int prio){
Entry entry = new Entry(data,prio);
Entry cur = this.head;
for(;cur.next != null;cur = cur.next){
if(cur.next.prio > prio){
break;
}
}
entry.next = cur.next ;
cur.next = entry;
}
b.出队
public void pop(){
Entry cur = this.head;
if(cur.next == null){
return;
}
cur.next = cur.next.next ;
}
优先级队列其它的操作和链式队列相同,可以参考上文的链式队列。