目录
栈(Stack)
栈: 一种特殊的线性表,其只允许在固定的一端进行插入和删除元素的操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈的数据元素遵循先进后出的原则。
压栈:栈的插入操作叫做进栈/压栈/入栈。入数据在栈顶
出栈:栈的删除操作叫出栈。出数据在栈顶。
栈遵循先进后出的原则,那出栈顺序为: 56 45 34 23 12。
队列(Queue)
队列:只允许在一端进行数据插入数据的操作,在另一端进行删除数据操作的特殊线性表。队列具有先进先出的原则。
入队列:进行插入操作的一端称为队尾。
出队列:进行删除操作的一端称为队头。
队列具有先进先出的原则,则出队的顺序为: 12 23 34 45 56。
队列的方法:
用单链表模拟实现队列:
队列具有先进先出的原则,我们入队的时候采用尾插法,出队的时候采用头删法。
public class MyQueue {
static class Node {
public int val;
public Node next;
public Node(int val) {
this.val = this.val;
}
}
public Node head;
public Node last;
public int usedSize;
/**
* 入队
* 使用尾插法
*/
public void offer(int val) {
Node node = new Node(val);
if(head == null) {
head = node;
last = node;
} else {
last.next = node;
last = node;
}
usedSize++;
}
/**
* 出队
*/
public int pool() {
if(empty()) {
throw new EmptyException("队列为空");
}
int ret = head.val;
head = head.next;
if(head == null) {
last = null;//只有一个节点,last也要置空
}
usedSize--;
return ret;
}
public boolean empty() {
return usedSize == 0;
}
/**
* 获取队头元素
*/
public int peek() {
if(empty()) {
throw new EmptyException("队列为空");
}
return head.val;
}
public int getUsedSize() {
return usedSize;
}
}
循环队列
当数组前面几个元素被删除,后面又已经满了的时候如何向数组插入元素?
public class MyCircularQueue {
private int[] elem;
private int front; // 队头
private int rear; // 队尾
public MyCircularQueue(int k) {
this.elem = new int[k+1];
}
/**
* 入队
*/
public boolean enQueue(int val) {
if(isFull()) {
return false;
}
elem[rear] = val;
rear = (rear+1) % elem.length;
return true;
}
/**
* 队列是否为满
*/
public boolean isFull() {
return (rear + 1) % elem.length == front;
}
/**
* 出队
*/
public boolean deQueue() {
if(isEmpty()) {
return false;
}
front = (front+1) % elem.length;
return true;
}
/**
* 得到队头元素
*/
public int Front() {
if(isEmpty()) {
return -1;
}
return elem[front];
}
/**
* 得到队尾元素
*/
public int rear() {
if(isEmpty()) {
return -1;
}
int index = (rear == 0) ? elem.length-1 : rear-1;
return elem[index];
}
/**
* 是否为空
*/
public boolean isEmpty() {
return front == rear;
}
}
队列实现栈
具体问题是用两个队列实现一个先进后出的栈,并且实现栈的push(),peek(),pop()和empty().
思路解析:
整体思路:
入栈:对两个队列进行检查, 入不为空的队列,若都为空则如qu1队列
出栈: 不为空的队列出size-1个元素到另外一个空队列里面去
将qu1里的元素取出来接可以了
获取栈顶元素
获取栈顶元素,需要将不为空的队列全部移到另外一个队列里面,每移出一个元素都用val记录,当最后一个元素移出来,val的值就是栈顶元素的值
public int top() {
if(empty()) {
return -1;//两个队列都为空,意味着当前的栈为空
}
if(!qu1.isEmpty()) {
int size = qu1.size();
int val = -1;
for (int i = 0; i < size; i++) {
val = qu1.poll();
qu2.offer(val);
}
return val;
}else {
int size = qu2.size();
int val = -1;
for (int i = 0; i < size; i++) {
val = qu2.poll();
qu1.offer(val);
}
return val;
}
}
判断是否为空
当qu1和qu2都为空的时候,队列就为空
栈实现队列
具体问题是用两个栈实现一个先进先出的队列,并实现队列的push(),pop(),peek(),empty()方法。
思路解析:
入队列: 将元素放到s1栈里面
出队列:首先检查s2的栈是否为空,若为空,将s1的元素先出栈,然后入到s2里面,s2的栈顶元素就是要出队列的元素.若两个栈都为空,则队列为空.
获取队头元素:思路和出队列类似,在最后一步直接获取s2的对头元素就可以.
判断是否为空:若s1和s2都为空,则队列为空