一、数组实现队列
数组实现队列有很大的劣势,比如:它容易造成存储空间的浪费,不易扩张等等。
解决办法:
(1) 动态扩充数组:入队时,先要判断当前元素是否能添加到数组中,如果数组已经满了则扩充数组,出对时:将前面的元素取出,赋空值。
(2)移动元素位置:出队时,后面的元素向前移动位置 缺点:每次出队都需要移动位置
(3)构造环形队列:真难过很好解决浪费存储空间的诟病。
1. 先定义一个存储队列元素的数组,定义数组长度,头指针,尾指针,和数组存储数据的个数,并初始化。
//定义一个数组
Object array[];
//数组存储数据的个数
private Integer size;
//头指针
private Integer head;
//尾指针
private Integer tail;
//数组长度
private Integer length = 10;
//构造方法
public ArrayMyQueue() {
array = new Object[length];
head = tail = size = 0;
}
2. 判断队列是否为空
当头指针等于尾指针时,队列为空,返回true.
//判断队列是否为空
public boolean isEmple() {
if(head == tail) {
return true;
}
return false;
}
3. 入队
先判断,当数组存储元素个数大于数组长度时,当前元素不能入队。
然后再判断,当队列为空的话,重置头尾指针,将新元素赋给队首,尾指针为1,数组存储元素个数自增。
不为空的话,直接将新元素赋给队尾,尾指针自增,数组存储元素自增。
//入队
public boolean add(E dex) {
//判断当前元素是否能加进去
if(size >= length) {
return false;
}
if(head == tail) { //为空的话重置头尾指针
head = 0;
array[head] = dex;
tail = 1;
size++;
return true;
}else {
array[tail] = dex;
tail++;
size++;
return true;
}
}
4. 出队
先判断队列是否为空,如果为空则返回空值。
反之,直接将队首元素赋给一个新的变量,头指针自增,数组存储元素个数自减,组后返回这个新的变量。
//出队
public E pop() {
//判断队列是否为空,如果为空返回空值
if(head == tail) {
return null;
}
E e = (E) array[head];
head = head+1;
size--;
return e;
}
5. 测试
public static void main(String[] args) {
ArrayMyQueue<Integer> s = new ArrayMyQueue<Integer>();
s.add(1);
s.add(2);
s.add(3);
s.add(4);
s.add(5);
System.out.println("队首元素为:"+s.pop());
System.out.println("队首元素为:"+s.pop());
System.out.println("队首元素为:"+s.pop());
}
6. 运行截图:
二、链表实现队列的操作
1. 首先编写一个节点类
package Queue;
public class Node<E> { //节点类
//当前节点
E data;
//下一个节点
Node<E> next;
//构造方法
public Node(E data) {
this.data = data;
}
}
2. 编写实现类MyQueue,首先定义两个私有的节点head和tail。并编写判断队列是否为空的isEmple方法。
//队首
private Node<E> head = null;
//队尾
private Node<E> tail = null;
//查看队列死否为空
public boolean isEmple() {
return head == null;
}
3. 入队:
创建一个新节点,当队首队尾都为空时,将新节点赋给队首队尾。反之将新节点赋给队首的下一个节点,将该节点作为队尾。
//入队
public void add(E dex) {
//创建一个新节点
Node<E> newNode = new Node<E>(dex);
if(head == null && tail == null) {
head = tail = newNode;
}else {
tail.next = newNode;
tail = newNode;
}
}
4. 出队:
首先直接调用isEmple()方法判断队列是否为空,如果为空的话直接返回空即可。反之将队首节点的值赋给一个变量,将队首节点的后继节点赋给队首节点,最后返回该变量。
//出队
public E pop() {
//判断队列是否为空
if(isEmple()) {
return null;
}
E nex = head.data;
head = head.next;
return nex;
}
5. 队列长度:
将队首节点赋给一个新节点,并应以一个int型的变量赋给一个空值,然后循环判断该新节点非空,变量自增,将新节点的后继节点赋给新节点。
//队列长度
public int size() {
Node<E> temp = head;
int i = 0;
while(temp != null) {
i++;
temp = temp.next;
}
return i;
}
6. 测试:
public static void main(String[] args) {
MyQueue<Integer> s = new MyQueue<Integer>();
s.add(1);
s.add(2);
s.add(3);
s.add(4);
System.out.println("队首元素为:"+s.pop());
System.out.println("队首元素为:"+s.pop());
System.out.println("队首元素为:"+s.pop());
}
7. 运行截图: