栈和队列是线性数据结构的典型代表,数组和链表的兄弟姐妹。按照存储方式可分为顺序存储结构和链式存储结构。
栈只允许在有序的线性资料集合的一端(称为堆栈顶端,top)进行入栈(push)和出栈(pop)的运算,是一种后进先出(Last in First Out)的数据结构,简称 LIFO。
后进先出即最后存入的数据在取出的时候会最先被取出。举个例子,比如厨房叠在一起的碗,先放上去的碗堆在下面,取出的时候最后拿出,后放上去的碗在最上面,取出的时候最先拿出。
堆栈常用一维数组或链表来实现,即顺序存储结构与链式存储结构。
队列是先进先出(FIFO, First-In-First-Out)的线性表。队列只允许在后端(称为rear)进行插入操作,在前端(称为front)进行删除操作。
队列常用一维数组或链表来实现,即顺序存储结构与链式存储结构。
队列的操作方式和堆栈类似,唯一的区别在于队列只允许新数据在后端进行添加。
使用数组实现栈
由于是使用数组实现的,所以初始化栈时需设置栈的大小。
// 数组栈
public class ArrayStack {
int maxSize;
int[] list; //数组模拟栈,数据放在该数组
int top = 0; //表示栈顶,初始化为0
// 初始化栈
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
list = new int[maxSize];
}
}
将要入栈的值存入数组中,同时指针top上移。
如果栈已经满了,则添加失败。
可以在栈满后创建一个更大的数组来优化操作
// 入栈操作
public void push(int val) {
if (top >= maxSize) {
System.out.println("The stack is max!");
} else {
list[top] = val;
top++;
}
}
top指针直接下移即可。
public void pop() {
if (top == 0) {
System.out.println("Error! The stack is empty!");
} else {
top--;
}
}
输出栈中的元素。
public void display() {
if(top == 0){
System.out.println("The stack is empty!");
return;
}
for(int i = 0; i < top; i++) {
System.out.print(list[i]+" ");
}
System.out.println();
}
top指针置于起点即可。
public void clear() {
top = 0;
}
public boolean isEmpty() {
if (top == 0) {
return true;
} else {
return false;
}
}
public Object peek() {
if (top != 0) {
return list[top-1];
} else {
return null;
}
}
// 数组栈
public class ArrayStack {
int maxSize;
int[] list; //数组模拟栈,数据放在该数组
int top = 0; //表示栈顶,初始化为0
// 初始化栈
public ArrayStack(int maxSize) {
this.maxSize = maxSize;
list = new int[maxSize];
}
// 入栈操作
public void push(int val) {
if (top >= maxSize) {
System.out.println("The stack is max!");
} else {
list[top] = val;
top++;
}
}
// 出栈操作
public void pop() {
if (top == 0) {
System.out.println("Error! The stack is empty!");
} else {
top--;
}
}
// 打印栈
public void display() {
if(top == 0){
System.out.println("The stack is empty!");
return;
}
for(int i = 0; i < top; i++) {
System.out.print(list[i]+" ");
}
System.out.println();
}
// 清空栈
public void clear() {
top = 0;
}
// 判空
public boolean isEmpty() {
if (top == 0) {
return true;
} else {
return false;
}
}
// 返回栈顶元素
public Object peek() {
if (top != 0) {
return list[top-1];
} else {
return null;
}
}
public static void main(String[] args) {
ArrayStack arrayStack = new ArrayStack(5);
System.out.println(arrayStack.isEmpty());
arrayStack.push(1);
arrayStack.push(2);
arrayStack.push(3);
arrayStack.push(4);
arrayStack.display();
arrayStack.pop();
arrayStack.display();
arrayStack.push(5);
arrayStack.display();
System.out.println(arrayStack.peek());
System.out.println(arrayStack.isEmpty());
arrayStack.clear();
arrayStack.display();
System.out.println(arrayStack.peek());
System.out.println(arrayStack.isEmpty());
}
}
使用链表实现栈
创建StackNode类,每个StackNode对象表示一个节点。
// 链栈
public class LinkStack{
// 链栈的结点构造
class StackNode{
int val; // 每个节点存放的值
StackNode next; // 指向下一个节点
StackNode() {
}
StackNode(int val) {
this.val = val;
}
StackNode(int val, StackNode next) {
this.val = val;
this.next = next;
}
}
int size = 0;
StackNode topNode;
}
即把元素插入栈顶,和头插法相同
// 入栈操作
public void push (int val) {
StackNode newStackNode = new StackNode();
newStackNode.val = val;
if (topNode == null) {
topNode = newStackNode;
size ++;
} else {
newStackNode.next = topNode;
topNode = newStackNode;
size ++;
}
System.out.println(val + " has been stacked!");
}
top指针直接下移即可。
public void pop() {
if (topNode == null) {
System.out.println("Error! The stack is empty!");
} else {
int popValue = topNode.val; // 接收一下出栈的元素,方便后面打印出来
topNode = topNode.next; // 栈顶指针(即链表头结点)直接指向下一个元素即可删除
size--;
System.out.println(popValue + " is out of stack!");
}
}
输出栈中的元素。
public void display() {
StackNode current = topNode;
while(current != null){
System.out.print(current.val);
if (current.next != null) {
System.out.print(" ");
}
current = current.next;
}
System.out.println();
}
清空topNode。
public void clear() {
if(topNode == null) {
System.out.println("The stack is empty!");
} else {
topNode = null;
System.out.println("Stack has been emptied!");
}
}
public boolean isEmpty() {
if (topNode == null) {
return true;
} else {
return false;
}
}
public int peek() {
if(topNode == null) {
System.out.println("The stack is empty!");
}
return topNode.val;
}
// 链栈
public class LinkStack {
// 链栈的结点构造
class StackNode{
int val; // 每个节点存放的值
StackNode next; // 指向下一个节点
StackNode() {
}
StackNode(int val) {
this.val = val;
}
StackNode(int val, StackNode next) {
this.val = val;
this.next = next;
}
}
int size = 0;
StackNode topNode;
// 入栈操作!即把元素插入栈顶,和头插法相同
public void push (int val) {
StackNode newStackNode = new StackNode();
newStackNode.val = val;
if (topNode == null) {
topNode = newStackNode;
size ++;
} else {
newStackNode.next = topNode;
topNode = newStackNode;
size ++;
}
System.out.println(val + " has been stacked!");
}
// 出栈操作!
public void pop () {
if (topNode == null) {
System.out.println("Error! The stack is empty!");
} else {
int popValue = topNode.val; // 接收一下出栈的元素,方便后面打印出来
topNode = topNode.next; // 栈顶指针(即链表头结点)直接指向下一个元素即可删除
size--;
System.out.println(popValue + " is out of stack!");
}
}
public void display () {
StackNode current = topNode;
while(current != null){
System.out.print(current.val);
if (current.next != null) {
System.out.print(" ");
}
current = current.next;
}
System.out.println();
}
public int peek() {
if(topNode == null) {
System.out.println("The stack is empty!");
}
return topNode.val;
}
public void clear () {
if(topNode == null) {
System.out.println("The stack is empty!");
} else {
topNode = null;
System.out.println("Stack has been emptied!");
}
}
public boolean isEmpty () {
if (topNode == null) {
return true;
} else {
return false;
}
}
public static void main(String[] args) {
LinkStack linkStack = new LinkStack();
linkStack.push(2);
linkStack.push(3);
linkStack.display();
linkStack.pop();
linkStack.display();
System.out.println("The topNode is "+linkStack.peek());
linkStack.clear();
System.out.println("The stack is null? "+linkStack.isEmpty());
linkStack.push(8);
linkStack.push(7);
linkStack.push(5);
linkStack.display();
System.out.println("The stack is null? "+linkStack.isEmpty());
}
}
使用数组实现队列
public class ArrayQueue {
int maxSize; // 队列最大容量
int[] list; //数组模拟队列,数据放在该数组
int front = 0; //队头指针front,指向队头元素
int rear = 0; //队尾指针rear,指向下一个入队元素的存储位置
int currentSize; // 记录当前队列有几个元素
// 初始化队列
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
list = new int[maxSize];
front = 0;
rear = 0;
currentSize = 0;
}
}
将要入队的值存入数组中,同时队尾指针rear后移。
如果队列已经满了,则添加失败。
可以在队列满后创建一个更大的数组来优化操作
// 入队
public void enQueue (int val) {
if (currentSize >= maxSize) {
System.out.println("Error! The queue is full!");
} else {
list[rear % maxSize] = val;
rear ++;
currentSize ++;
System.out.println(val + " has been queued!");
}
}
队头指针front后移
public void deQueue () {
if (currentSize == 0) {
System.out.println("Error! The queue is empty!");
} else {
int dequeueValue = list[front];
front = (front + 1) % maxSize;
currentSize --;
System.out.println(dequeueValue + " is dequeued!");
}
}
输出队列中的元素。
public void display() {
if(rear == front){
System.out.println("The queue is empty!");
return;
}
for(int i = front; i < rear; i++) {
System.out.print(list[i % maxSize]+" ");
}
System.out.println();
}
package queue;
// 队列
public class ArrayQueue {
int maxSize; // 队列最大容量
int[] list; //数组模拟队列,数据放在该数组
int front = 0; //队头指针front,指向队头元素
int rear = 0; //队尾指针rear,指向下一个入队元素的存储位置
int currentSize; // 记录当前队列有几个元素
// 初始化队列
public ArrayQueue(int maxSize) {
this.maxSize = maxSize;
list = new int[maxSize];
front = 0;
rear = 0;
currentSize = 0;
}
// 入队
public void enQueue (int val) {
if (currentSize >= maxSize) {
System.out.println("Error! The queue is full!");
} else {
list[rear % maxSize] = val;
rear ++;
currentSize ++;
System.out.println(val + " has been queued!");
}
}
// 出队
public void deQueue () {
if (currentSize == 0) {
System.out.println("Error! The queue is empty!");
} else {
int dequeueValue = list[front];
front = (front + 1) % maxSize;
currentSize --;
System.out.println(dequeueValue + " is dequeued!");
}
}
public void display () {
if(rear == front){
System.out.println("The queue is empty!");
return;
}
for(int i = front; i < rear; i++) {
System.out.print(list[i % maxSize]+" ");
}
System.out.println();
}
public static void main(String[] args) {
ArrayQueue arrayQueue = new ArrayQueue(9);
arrayQueue.enQueue(1);
arrayQueue.enQueue(2);
arrayQueue.enQueue(3);
arrayQueue.enQueue(4);
arrayQueue.enQueue(5);
arrayQueue.enQueue(6);
arrayQueue.enQueue(7);
arrayQueue.enQueue(8);
arrayQueue.enQueue(9);
arrayQueue.display();
arrayQueue.deQueue();
arrayQueue.enQueue(1);
arrayQueue.display();
}
}
使用链表实现队列
创建QueueNode对象表示队列节点。声明队头指针和队尾指针。
// 链式队列
public class LinkQueue {
// 链式队列的结点构造
static class QueueNode{
int val;
QueueNode next;
// 初始化栈
QueueNode() {
}
QueueNode(int val) {
this.val = val;
}
QueueNode(int val, QueueNode next) {
this.val = val;
this.next = next;
}
}
int size = 0; // 记录当前队列有几个元素
QueueNode front; // 队头指针front,指向队头元素
QueueNode rear; // 队尾指针rear,指向下一个入队元素的存储位置
QueueNode back; // 队尾指针back,指向队尾元素
}
将要入队的值存入QueueNode 对象中,同时队尾指针后移。
// 入队
public void enQueue (int val) {
QueueNode queueNode = new QueueNode();
queueNode.val = val;
if (front == null) {
front = queueNode;
back = queueNode;
System.out.println(val + " has been queued!");
size ++;
} else {
back.next = queueNode;
back = back.next;
System.out.println(val + " has been queued!");
size ++;
}
}
队头指针front后移
public void deQueue () {
if (front == null) {
System.out.println("Error! The queue is empty!");
} else {
front = front.next;
}
}
输出队列中的元素。
public void display () {
QueueNode current = front;
while(current != null){
System.out.print(current.val);
if (current.next != null) {
System.out.print(" ");
}
current = current.next;
}
System.out.println();
}
package queue;
// 链式队列
public class LinkQueue {
// 链式队列的结点构造
static class QueueNode{
int val;
QueueNode next;
// 初始化栈
QueueNode() {
}
QueueNode(int val) {
this.val = val;
}
QueueNode(int val, QueueNode next) {
this.val = val;
this.next = next;
}
}
int size = 0; // 记录当前队列有几个元素
QueueNode front; // 队头指针front,指向队头元素
QueueNode rear; // 队尾指针rear,指向下一个入队元素的存储位置
QueueNode back; // 队尾指针back,指向队尾元素
public void enQueue(int val) {
QueueNode queueNode = new QueueNode();
queueNode.val = val;
if (front == null) {
front = queueNode;
back = queueNode;
System.out.println(val + " has been queued!");
size ++;
} else {
back.next = queueNode;
back = back.next;
System.out.println(val + " has been queued!");
size ++;
}
}
public void deQueue() {
if (front == null) {
System.out.println("Error! The queue is empty!");
} else {
front = front.next;
}
}
public void display () {
QueueNode current = front;
while(current != null){
System.out.print(current.val);
if (current.next != null) {
System.out.print(" ");
}
current = current.next;
}
System.out.println();
}
public static void main(String[] args) {
LinkQueue linkQueue = new LinkQueue();
linkQueue.enQueue(1);
linkQueue.enQueue(2);
linkQueue.enQueue(3);
linkQueue.enQueue(4);
linkQueue.display();
linkQueue.deQueue();
linkQueue.display();
}
}