目录
1.基于链表实现的队列的特点
队列从队尾入队,队首出队(头插尾删、头删尾插都可以)FIFO。
时间复杂度为O(n)。
2.入队offer
@Override public void offer(E val) { //对Queue接口中所有的方法进行覆写 Node node =new Node(val); if (head == null) { head=tail=node; }else { tail.next=node; tail=node; } size++; }
3.返回队首元素peek
/*出队*/ @Override public E peek() { if(isEmpty()){ throw new NoSuchElementException("queue is empty,can not pool"); } return head.val; }
4.出队poll
/*返回队首元素*/ @Override public E poll() { if(isEmpty()){ throw new NoSuchElementException("queue is empty,can not peek"); } E val= head.val; Node node =head; head=head.next; //将原来头节点脱钩 node.next=null; return val; }
完整代码
package stack_queue.stack.queue;
import stack_queue.stack.queue.impl.Queue;
import java.util.NoSuchElementException;
/*基于链表实现的基础队列*/
public class MyQueue <E> implements Queue<E> {
//------------------------------------------------
//设立一个内部类存储链表的每个节点,私有内部类,对外部来说完全隐藏,只是我这个类中自己去使用
private class Node{
E val;
Node next;
public Node(E val){ //利用这个方法把值传给 Node node = new Node(val);
this.val=val;
}
}
//--------------------------------------------------
//当前队列的元素个数
private int size;
//队首
private Node head;
//队尾
private Node tail;
/*尾插
* */
@Override
public void offer(E val) { //对Queue接口中所有的方法进行覆写
Node node =new Node(val);
if (head == null) {
head=tail=node;
}else {
tail.next=node;
tail=node;
}
size++;
}
/*出队*/
@Override
public E peek() {
if(isEmpty()){
throw new NoSuchElementException("queue is empty,can not pool");
}
return head.val;
}
/*返回队首元素*/
@Override
public E poll() {
if(isEmpty()){
throw new NoSuchElementException("queue is empty,can not peek");
}
E val= head.val;
Node node =head;
head=head.next;
//将原来头节点脱钩
node.next=null;
return val;
}
public boolean isEmpty(){
return size==0;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("front [");
// 链表的遍历
for (Node x = head;x != null;x = x.next) {
sb.append(x.val);
if (x.next != null) {
// 还没走到链表尾部
sb.append(", ");
}
}
sb.append("]");
return sb.toString();
}
}
自己实现的接口如下
package stack_queue.stack.queue.impl;
//泛型接口,支持多种类型
public interface Queue<E> {
//入队
void offer(E val);//入队不需要返回值
//出队
E poll( );//他们俩返回任意类型也就是E类型
E peek( );
boolean isEmpty();
}
如下实现了循环队列
package stack_queue.stack.queue.impl; import java.util.Arrays; import java.util.NoSuchElementException; public class LoopQueue implements Queue<Integer>{ //普通数组 private Integer[] data; //队首元素1 private int head; //指向队尾元素的下一个位置 private int tail; //当前队列中元素个数 private int size; //n为希望保存的元素个数 public LoopQueue(int n){ //因为保存的元素的元素要空一位,查看队列是否已满 data =new Integer[n+1]; } //添加一个元素,入栈 @Override public void offer(Integer val) { if(isFull()){ throw new ArrayIndexOutOfBoundsException("Queue is full,cannot offer new value "); } data[tail]=val; tail=tail+1%data.length; size++; } //出栈操作 @Override public Integer poll() { if(isEmpty()){ throw new NoSuchElementException("queue is empty"); } Integer val =data[head]; head=(head+1)% data.length; size--; return val; } //返回栈顶元素 @Override public Integer peek() { if(isEmpty()){ throw new NoSuchElementException("queue is empty"); } return data[head]; } @Override public String toString() { StringBuilder sb =new StringBuilder(); sb.append("front["); //取得最后一个元素的下标 int LastIndex =tail ==0?data.length-1:tail-1; for (int i = head; i<tail;) { sb.append(data[i]); i=(i+1)%data.length; //因为i加一了,所以需要最后的索引也加1 if(i!=(LastIndex+1)){ sb.append(","); } } sb.append("]"); return sb.toString(); } @Override public boolean isEmpty() { return tail==head; } public boolean isFull(){ return (tail+1)% data.length==head; } }