队列的概念
队列是另一种限定性线性表,它只允许插入在表的一端进行,而删除在表的另外一端进行,我们将这种数据结构称为队或者队列。
队的删除操作称为出队,队的插入操作称为入队列或者进队列。
当队列中无元素时,我们称为空队列。
队头元素总是最先进队列的,也是最先出队列的;队尾元素总是最后进队列,也是最后出队列的,因此队列也被称为**“先进先出”**表,这与我们在生活中排队买东西一样。
队列的链表实现
创建节点:
public class Node<E> {
public E data;
public Node<E> next;
public Node() {
}
public Node(E data, Node<E> next) {
this.data = data;
this.next = next;
}
public E getData() {
return data;
}
public void setData(E data) {
this.data = data;
}
public Node<E> getNext() {
return next;
}
public void setNext(Node<E> next) {
this.next = next;
}
@Override
public String toString() {
return "Node [data=" + data + ", next=" + next + "]";
}
}
造队列:
public class MyQueue<E> {
private Node<E> head; // 表头
private Node<E> tail; // 表尾
private int size; // 容量大小
public boolean isEmpty() {
return this.size == 0;
}
public int size() {
return this.size;
}
1.入队列—.offer()
/**
* 入队--offer
*/
public void offer(E e) {
final Node<E> newNode = new Node<>(e, null);
if (isEmpty()) { // 空队列时
head = newNode;
tail = newNode;
} else { // 不为空队列时
Node<E> last = tail; //尾插
last.next = newNode;
tail = newNode;
}
this.size++;
}
测试:
@Test
public void test() {
MyQueue<Integer> q = new MyQueue<>();
q.offer(1);
q.offer(2);
q.offer(3);
q.offer(4);
q.offer(5);
q.offer(6);
System.out.println(q);
2.获取队头—.peek()
/**
* 获得队头---peek
*/
public E peek() {
if (isEmpty()) {
throw new QueueExeception("空队列异常");
}
return head.data;
}
测试:
@Test
public void test() {
MyQueue<Integer> q = new MyQueue<>();
q.offer(1);
q.offer(2);
q.offer(3);
q.offer(4);
q.offer(5);
q.offer(6);
System.out.println(q.peek());
3.出队列—.poll()
/**
* 出队列——poll
*/
public E poll() {
E e = peek(); // 获得队头
Node<E> first = head; // 头结点
Node<E> second = head.next; // 第二个节点
first.next = null; // 先让第一个节点滞空
head = second;
this.size--;
return e;
}
测试:
@Test
public void test() {
MyQueue<Integer> q = new MyQueue<>();
q.offer(1);
q.offer(2);
q.offer(3);
q.offer(4);
q.offer(5);
q.offer(6);
System.out.println(q);
System.out.println("删除后:");
q.poll();
q.poll();
System.out.println(q);
剑指 Offer 09. 用两个栈实现队列
class CQueue {
Stack<Integer> stackA;
Stack<Integer> stackB;
public CQueue() {
stackA = new Stack<Integer>();
stackB = new Stack<Integer>();
}
public void appendTail(int value) { //队尾插入元素
stackA.push(value); // 直接利用push()即可完成 (将新节点直接插入链表)
}
public int deleteHead() { //队头删除元素
if (stackA.isEmpty() && stackB.isEmpty()) { // 如果两个栈中数据都为空时直接返回-1
return -1;
}
while (!stackA.isEmpty()) {
int value = stackA.pop();
stackB.push(value);
}
int value = stackB.pop();
while (!stackB.isEmpty()) {
stackA.push(stackB.pop());
}
return value;
}
}