您的位置:首页 > 理论基础 > 数据结构算法

java实现数据结构之普通队列

2019-05-20 15:27 302 查看
版权声明:https://blog.csdn.net/weixin_41347419 https://blog.csdn.net/weixin_41347419/article/details/90375809

队列接口

/**
*   队列接口
*
*/
public interface MyQueue<E> {

int getSize();  	//当前队列元素个数

boolean isEmpty(); 	//队列是否为空

void enqueue(E e);   //入队

E dequeue();//出队

E getFront(); //获取队首元素
}

基于链表实现的普通队列

public class MyLinkListQueue<E>  implements MyQueue<E> {

/**
*   内部节点类
*/
private class Node{
public E e;
public Node next;

public Node(E e, Node next){
this.e = e;
this.next = next;
}

public Node(E e){
this(e, null);
}

public Node(){
this(null, null);
}

@Override
public String toString(){
return e.toString();
}
}
//队列头指针,尾指针
private Node head, tail;
//队列元素个数
private int size;

public MyLinkListQueue(){
head = null;
tail = null;
size = 0;
}

@Override
public int getSize() {
return size;
}

@Override
public boolean isEmpty() {
return size==0;
}

@Override
public void enqueue(E e) {
if (size == 0){
head = new Node(e);
tail = head;
}else {
tail.next = new Node(e); //入队元素添加到尾节点后
tail = tail.next;
}
size++;
}

@Override
public E dequeue() {
if(isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
//队头出队
Node ret = head;
head = head.next;
ret.next = null;
size--;
//如果出队后队列为空更新尾指针
if (head == null )
tail= null;

return ret.e;
}

@Override
public E getFront() {
if(isEmpty())
throw new IllegalArgumentException("Queue is empty.");
return head.e;
}

@Override
public String toString(){
StringBuilder res = new StringBuilder();
res.append("Queue: front ");

Node cur = head;
while(cur != null) {
res.append(cur + "->");
cur = cur.next;
}
res.append("NULL tail");
return res.toString();
}
}

基于动态数组实现的普通循环队列

/**
*   循环数组队列
*
*   设置:
*      队空条件: front == tail
*      队满条件:  tail + 1 == front  ,放弃一个空间用来判断队满
*/
public class MyLoopArrayQueue<E> implements MyQueue<E> {

private E[] data;     //数组队列
private int front;  //队首指针,指向队列第一个元素
private int tail;   //队尾指针, 指向下一个待插入元素队位置
private int size;  //当前队列的元素个数

public MyLoopArrayQueue(int capacity) {
this.data = (E[]) new Object[capacity + 1];
this.front = 0;
this.tail = 0;
this.size = 0;
}

public MyLoopArrayQueue() {
this(10);
}

//获取队列的最大容量
public int getCapacity() {
return data.length - 1;  //放弃了一个队列空间用来判断队满
}

@Override
public int getSize() {
return this.size;
}

@Override
public boolean isEmpty() {
return front == tail;
}

@Override
public void enqueue(E e) {
//队满,则扩容
if ((tail + 1) % data.length == front)
this.resize(getCapacity() * 2);

data[tail] = e;     //添加到队尾
tail = (tail + 1) % data.length;  //更新尾指针
size++;
}

@Override
public E dequeue() {
//队空
if (this.isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty queue.");
//出队,删除尾节点
E ret = data[front];
data[front] = null;
front = (front + 1) % data.length;  //更新尾指针
size--;

//出队判断队列是否需要缩容, 当size = 队列容量的1/4 时进行缩容
if(size == data.length / 4){
resize(getCapacity() / 2);
}

return ret;
}

@Override
public E getFront() {
//队空
if (this.isEmpty())
throw new IllegalArgumentException("Cannot dequeue from an empty queue.");

return data[front];   //查看队首元素
}

//改变容量
private void resize(int newCapacity) {
//新创建一个更大的数组,把原数组的值复制过去,再重新初始化队列头,尾指针即可。
E[] arr = (E[]) new Object[newCapacity + 1];

for (int i = 0; i < getSize(); i++) {
arr[i] = data[(front + i) % data.length];
}

//指向新队列,重新初始化指针
data = arr;
front = 0;
tail = size;
}

@Override
public String toString() {
StringBuilder res = new StringBuilder();
res.append(String.format("Queue: size = %d , capacity = %d\n", size, getCapacity()));
res.append("front [");
for(int i = front ; i != tail ; i = (i + 1) % data.length){
res.append(data[i]);
if((i + 1) % data.length != tail)
res.append(", ");
}
res.append("] tail");
return res.toString();
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: