栈和队列
- 栈
- 入栈
- 出栈
- 栈的JAVA实现
- 队列
- 入队
- 出队
- 循环队列
栈和队列。这两者都属于逻辑结构,它们的物理实现既可以利用数组,也可以利用链表来完成。
栈
栈(stack)是一种线性数据结构,它就像一个上图所示的放入乒乓球的圆筒容器,栈中的元素只能先入后出(First In Last Out,简称FILO)。
最早进入的元素存放的位置叫作栈底(bottom),最后进入的元素存放的位置叫作栈顶
(top)。
栈的数组实现
栈的链表实现
入栈
入栈操作(push)就是把新元素放入栈中,只允许从栈顶一侧放入元素,新元素的位置将会成为新的栈顶。
出栈
出栈操作(pop)就是把元素从栈中弹出,只有栈顶元素才允许出栈,出栈元素的前一个元素将会成为新的栈顶。
栈的JAVA实现
package dataStructure.myStack;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.EmptyStackException;
public class myStack <E>{
private Object[]arr;
//数组默认长度
private int stackLength=4;
private int size;
//指针
private int index = -1;
//判断栈是否为空
public boolean empty(){
return this.size==0;
}
//获取栈顶元素
public E pop(){
if(this.index==-1){
throw new IndexOutOfBoundsException("空栈,无法取元素");
}
this.size--;
return (E) this.arr[index--];
}
/**
* 数组初始化或者以 1.5 倍容量对数组扩容
*/
private void capacity(){
if(this.arr==null){
this.arr = new Object[this.stackLength];
}
if(this.size-(this.stackLength-1)>=0){
this.stackLength = this.stackLength+this.stackLength/2;
this.arr = Arrays.copyOf(this.arr,this.stackLength);
}
}
//向栈容器添加元素
public E push(E item){
this.capacity();
this.arr[++index]=item;
this.size++;
return item;
}
public static void main(String[] args) {
myStack<String> myStack = new myStack<>();
myStack.push("a");
myStack.push("b");
myStack.push("c");
System.out.println(myStack.pop());
System.out.println(myStack.empty());
System.out.println(myStack.pop());
System.out.println(myStack.pop());
System.out.println(myStack.empty());
System.out.println(myStack.pop());
}
}
队列
队列(queue)是一种线性数据结构,它的特征和行驶车辆的单行隧道很相似。不同于栈的先入后出,队列中的元素只能先入先出(First In First Out,简称(FIFO)。队列的出口端叫作队头(front),队列的入口端叫作队尾(rear)。
队列这种数据结构既可以用数组来实现,也可以用链表来实现。
队列数组实现
队列链表实现
入队
入队(enqueue)就是把新元素放入队列中,只允许在队尾的位置放入元素,新元素的下一个位置将会成为新的队尾。
出队
出队操作(dequeue)就是把元素移出队列,只允许在队头一侧移出元素,出队元素的后一个元素将会成为新的队头。
循环队列
数组实现的队列可以采用循环队列的方式来维持队列容量的恒定。
以利用已出队元素留下的空间,让队尾指针重新指回数组的首位。
在物理存储上,队尾的位置也可以在队头之前。当再有元素入队时,将其放入数组的首位,队尾指针继续后移即可。
队列满的条件:(队尾下标+1)%数组长度 = 队头下标