队列,是一种特殊的链表,是一种只能在表尾进行插入,表头进行删除的特殊链表,是一种先进先出的结构。
一、队列的结构
队列本质是一种链表,因此栈存储结构与链表一致,形象图如下:
整个栈像我们日常生活中的排队,每个排队的人物就是一个队列元素,新来的人只能排在队尾,从开始依次出队
1.给队列添加元素
- 就像在食堂打饭,后来的人就得在队列后面排着,前面的人先到打饭窗口打饭
2.从队列里面删除元素
- 在食堂打饭,队列的第一个人,排在打饭窗口,他打完饭,就离开这个队列了
二、通过数组实现栈
通过数组来实现栈是比较简单的,因为栈只操作表尾,即数组的最后一个元素,其主要操作主要是入栈和出栈。
1.入列
在队尾添加节点
2.出列
弹出队首元素节点
3.通过数组来实现队列这种数据结构
package com.shixinke.demo.dataStruct;
public class MyArrayQueue<E> {
/**
* 队列长度
*/
private int size;
/**
* 队列数据
*/
private E[] data;
/**
* 默认队列长度
*/
private static final int DEFAULT_CAPACITY = 10;
public MyArrayQueue() {
clearQueue(DEFAULT_CAPACITY);
}
public MyArrayQueue(int capacity) {
clearQueue(capacity);
}
public void clear() {
clearQueue(DEFAULT_CAPACITY);
}
public int size() {
return this.size;
}
public boolean isEmpty() {
return this.size == 0;
}
/**
* 入列
* @param element
* @return
*/
public boolean push(E element) {
if (size == data.length) {
ensureCapacity(size * 2 +1);
}
data[size] = element;
size ++;
return true;
}
/**
* 出列
* @return
*/
public E shift() {
if (size == 0) {
return null;
}
E node = data[0];
for (int i = 0; i< size - 1; i++) {
data[i] = data[i+1];
}
data[size -1] = null;
this.size --;
return node;
}
public boolean contains(E element) {
return indexOf(element) >= 0 ? true : false;
}
public int indexOf(E element) {
if (element == null) {
for (int i = 0; i< this.size; i++) {
if (data[i] == null) {
return i;
}
}
} else {
for (int i = 0; i< this.size; i++) {
if (element.equals(data[i])) {
return i;
}
}
}
return -1;
}
public int lastIndexOf(E element) {
if (element == null) {
for (int i = this.size -1; i >= 0; i -- ) {
if (data[i] == null) {
return i;
}
}
} else {
for (int i = this.size -1; i >= 0; i -- ) {
if (element.equals(data[i])) {
return i;
}
}
}
return -1;
}
public void print() {
System.out.println();
System.out.print("[");
for (int i = 0; i< this.size; i++) {
System.out.print(data[i]);
if (i != this.size - 1) {
System.out.print(",");
}
}
System.out.println("]");
System.out.println();
}
public static void main(String[] args) {
MyArrayQueue<String> books = new MyArrayQueue<String>(5);
books.push("JAVA编程");
books.push("网络安全");
books.push("计算机网络");
books.push("计算机文化基础");
books.print(); //[JAVA编程,网络安全,计算机网络,计算机文化基础]
String lastBook = books.shift();
System.out.println(lastBook); //JAVA编程
books.print(); //[网络安全,计算机网络,计算机文化基础]
System.out.println(books.size()); //3
System.out.println(books.contains("计算机网络")); //true
System.out.println(books.indexOf("计算机网络")); //1
}
private void clearQueue(int capacity) {
this.size = 0;
ensureCapacity(capacity);
}
private void ensureCapacity(int capacity) {
if (capacity < this.size) {
return;
}
E[] oldData = data;
data = (E[]) new Object[capacity];
for (int i = 0; i < this.size; i++) {
data[i] = oldData[i];
}
}
}
三、通过链表实现队列
1.入列
- 生成一个新的节点(它的prev指针指向表尾节点,next指针指向null)
- 将原表尾节点的next指针指向新表尾节点
- 将新表尾指向新的表尾节点
- 表节点个数加1
2.出列
- 将原表头节点的下一个节点的prev指向指向null
- 将表头指向原节点的下一个节点
- 清除了原表头的资源,内容和next指针都为null
- 表节点个数减1
3.通过链表实现栈
package com.shixinke.demo.dataStruct;
public class MyLinkedQueue<E> {
/**
* 队列长度
*/
private int size;
/**
* 队头
*/
private Node<E> head;
/**
* 队尾
*/
private Node<E> tail;
public MyLinkedQueue() {
clearQueue();
}
public void clear() {
clearQueue();
}
private void clearQueue() {
head = null;
tail = null;
size = 0;
}
public int size() {
return size;
}
public boolean isEmpty() {
return size == 0 ;
}
/**
* 入列
* @param element
* @return
*/
public boolean push(E element) {
//1.生成新元素节点,它的上一个元素为原表尾
Node<E> newNode = new Node(element, tail, null);
//2.如果表头是空,那么新元素就是表头
if (head == null) {
head = newNode;
}
//4.如果原队列不为空,那么原表尾的下个元素为新节点
tail.next = newNode;
//5.新表必为新节点
tail = newNode;
//6.增加队列的个数
size ++;
return true;
}
/**
* 入列
* @return
*/
public E shift() {
//1.如果表头为null,即是空队列,立即返回
if (head == null) {
return null;
}
//2.获取原表头的元素
E item = head.item;
//3.获取原表头的下一个元素
Node<E> newHead = head.next;
if (newHead != null) {
//如果存在下一个元素,将下一个元素的prev指向null
head.next.prev = null;
}
//4.清除原表头的资源
head.next = null;
head.item = null;
//5.设置新表头
head = newHead;
//6.队列元素个数减1
size --;
return item;
}
public boolean contains(E element) {
return indexOf(element) >= 0;
}
public int indexOf(E element) {
if (head == null) {
return -1;
}
Node<E> p = head;
if (element == null) {
for (int i = 0; i< size; i++) {
if (p.item == null) {
return i;
}
p = p.next;
}
} else {
for (int i = 0; i< size; i++) {
if (element.equals(p.item)) {
return i;
}
p = p.next;
}
}
return -1;
}
public int lastIndexOf(E element) {
if (tail == null) {
return -1;
}
Node<E> p = tail;
if (element == null) {
for (int i = size -1; i >= 0; i--) {
if (p.item == null) {
return i;
}
p = p.next;
}
} else {
for (int i = size -1; i >= 0; i--) {
if (element.equals(p.item)) {
return i;
}
p = p.next;
}
}
return -1;
}
public void print() {
System.out.println();
Node<E> node = head;
System.out.print("[");
for (int i = 0; i< this.size; i++) {
System.out.print(node.item);
node = node.next;
if (node != null) {
System.out.print(",");
}
}
System.out.print("]");
System.out.println();
}
public static void main(String[] args) {
MyLinkedQueue<String> books = new MyLinkedQueue<String>();
books.push("JAVA编程");
books.push("网络安全");
books.push("计算机网络");
books.push("计算机文化基础");
books.print(); //[JAVA编程,网络安全,计算机网络,计算机文化基础]
String lastBook = books.shift();
System.out.println(lastBook); //JAVA编程
books.print(); //[网络安全,计算机网络,计算机文化基础]
System.out.println(books.size()); //3
System.out.println(books.contains("计算机网络")); //true
System.out.println(books.indexOf("计算机网络")); //1
}
/**
* 队列节点
* @param <E>
*/
private class Node<E> {
/**
* 前节点
*/
private Node<E> prev;
/**
* 后节点
*/
private Node<E> next;
/**
* 节点元素
*/
private E item;
public Node(E item, Node<E> prev, Node<E> next) {
this.item = item;
this.prev = prev;
this.next = next;
}
}
}