关于队列的简单介绍
队列:先进先出。数据按照a,b,c的顺序进去,也会按照a,b,c的顺序出来
栈:先进后出、后进先出。 弹夹形式,数据以a,b,c的形式进去,却以c,b,a的顺序出来,先进的数据会被压在栈底。
如何使用单链表来实现队列和栈。
队列:如果head、tail节点为null,说明此时队列中没有节点,则构建一个节点,head、tail共同指向它。如果不为null,说明队列中有节点,让上一个tail的next指向当前节点,并将当前节点作为新的tail节点
public static class Node<V> {
public V value;
public Node<V> next;
public Node(V value) {
value = value;
next = null;
}
}
public static class MyQueue<V>{
private Node<V> head;
private Node<V> tail;
private int size;
public MyQueue(){
head = null;
tail = null;
size = 0;
}
public boolean isEmpty(){
return size ==0;
}
public int size(){
return size;
}
public void offer(V value){
Node node = new Node(value);
if (tail == null){
head = node;
tail = node;
}else{
tail.next = node;
tail = node;
}
size++;
}
public V poll(){
V ans = null;
if (head != null){
ans = head.value;
head = head.next;
size --;
}
if (head == null){
tail = null;
}
return ans;
}
public V peek(){
V ans = null;
if (head != null){
ans = head.value;
}
return ans;
}
}
栈:比队列更加简单,只需要head一个变量即可,每次将新数据的next指向原先的老head节点,并将自己作为新的head节点
public static class MyStack<V> {
private Node<V> head;
private int size;
public MyStack() {
head = null;
size = 0;
}
public boolean isEmpty() {
return size == 0;
}
public int size() {
return size;
}
public void push(V value) {
Node node = new Node(value);
if (head == null) {
head = node;
} else {
node.next = head;
head = node;
}
size++;
}
public V poll() {
V ans = null;
if (head != null) {
ans = head.value;
head = head.next;
size--;
}
return ans;
}
public V peek() {
return head == null ? null : head.value;
}
}
如何使用数组实现队列和栈
用数组实现栈很简单,只需要声明index一个变量,初始值为0,每次元素增加的位置就是index处的位置,之后index++即可,取则看index是否为0,不为0代表数组中有元素。取完后index–。
public static class ArrayStack {
private int limit;
private int index;
private int[] arr;
public ArrayStack(int limit) {
arr = new int[limit];
index = 0;
this.limit = limit;
}
public void push(int value) {
if (index == limit) {
throw new RuntimeException("队列已经满了");
}
arr[index] = value;
index++;
}
public int poll() {
int ans;
if (index == 0) {
throw new RuntimeException("队列为空");
}
ans = arr[index];
index--;
return ans;
}
public boolean isEmpty() {
return index == 0;
}
}
用数组实现队列比较复杂,因为队列先进先出,如果声明takeIndex用来表示取的下标,用putIndex来表示存的下标,每次存取下标对应进行++操作的话,乍一看很方便,但如果数组中再添加新的元素呢? 如果put指针和take指针碰撞了呢?
如果take指针和put指针碰撞之后,你会发现,你不知道要取的位置有没有元素可以返回,会变得很麻烦,所以还可以额外引入一个变量,专门用来记录当前数组中元素的个数,达到彻底解耦的目的。
//数组实现队列(先进先出)
public static class ArrayQueue {
private int limit;
private int takeIndex;
private int putIndex;
private int[] arr;
private int size;
public ArrayQueue(int limit) {
this.putIndex = 0;
this.takeIndex = 0;
this.size = 0;
arr = new int[limit];
this.limit = limit;
}
public void push(int value) {
if (size == limit) {
throw new RuntimeException("队列已满");
}
size++;
arr[putIndex] = value;
putIndex = setIndex(putIndex);
}
public int poll(){
if (size == 0){
throw new RuntimeException("队列中无元素");
}
int ans;
size--;
ans = arr[takeIndex];
takeIndex = setIndex(takeIndex);
return ans;
}
public int setIndex(int i) {
return i == limit - 1 ? 0 : i + 1;
}
}