目录
1.栈的概念:
栈是一种特殊的线性表,其只允许在固定的一端插入和删除操作。进行数据插入和删除的一端叫做栈顶,另一端叫做栈底。数据遵守先入后出的原则。
压栈:数据的插入,数据在栈底。
出栈:数据的删除,数据在栈顶。
2.栈的一些常用的方法:
public boolean empty() {
return size() == 0;
}
public synchronized boolean isEmpty() {
return elementCount == 0;
}
这两种方法均可判断栈是否为空
3.栈的模拟实现:
从图上看出:Stack继承了Vector,ArrayList和Vector类似,都是动态顺序表,但Vector是线程安全的。
public class MyStack {
public int[] elem;
public int Usedsice; //记录栈的有效数据个数
public MyStack() {
this.elem = new int[10]; //初始化空间大小
}
//数据的弹出删除操作
public int pop(){
if (empty()){ //首先判断是否为空
return -1;
}
Usedsice--; //栈总是弹出栈尾,就是最后一个元素
return this.elem[Usedsice];
}
//判断是否为空
public boolean isFull() {
//当栈的长度等于有效数据的个数即满
return this.elem.length == Usedsice;
}
public void push(int index) {
if (isFull()) {
//TODO 扩容,以二倍大小扩容
this.elem = Arrays.copyOf(elem, 2 * elem.length);
}
this.elem[Usedsice] = index;
Usedsice++;
}
public boolean empty() {
return Usedsice == 0;
}
public int peek(){
if(empty()){
return -1;
}
return this.elem[Usedsice-1];
}
public void print(){
if(empty()){
return;
}
for(Integer x:this.elem){
System.out.print(x+" ");
}
System.out.println();
}
}
栈的应用:
1.若进栈序列为1,2,3,4,进栈过程中可以出栈,则下列不可能的一个出栈顺序是(C)
A.1,4,3,2 B.2,3,4,1 C.3,1,4,2 D.3,4,2,1
C:3已经进去了,说明1,2也都进去了没有出来,此时出来3,要想接着出来1,必须再把2出栈,所以C错误。
4.关于栈的练习
1.括号匹配:. - 力扣(LeetCode)
2.波兰表达式求值:. - 力扣(LeetCode)
3.出入栈的顺序:栈的压入、弹出序列_牛客题霸_牛客网
4.最小栈:. - 力扣(LeetCode)
5.队列的概念:
只允许在一端进行插入,另一端进行删除的操作的线性表,有先进先出的性质。
队尾:数据插入的一端;
队首:数据删除的一端;
6.队列的使用:
在java中,Queue是个接口,底层是链表实现的。但是队列有链式结构和顺序结构之分。
队列的主要方法:
offer():插入在队尾元素,是返回值boolean类型
poll():在对头删除元素,返回值为删除的数据
peek():获取队头元素
remove():删除队头元素,并返回被删除的元素
7.模拟队列
public class MyQueue {
// TODO 队列底层由链表实现,定义一个节点
static class ListNode{
public int val;
public ListNode prev;
public ListNode next;
public ListNode(int val){
this.val = val;
}
}
ListNode first; //头尾节点
ListNode last;
//TODO 队列尾进头出
public void offer(int val){
ListNode temp = new ListNode(val);
if(isEmpty()){
first = last = temp;
}
else
{
//尾插,再将尾节点置为last
last.next = temp;
temp.prev = last;
last = last.next;
}
}
public int poll(){
if (isEmpty()){
return -1;
}else {
first = first.next;
first.prev = null;
}
return first.val;
}
public int peek(){
if (isEmpty()){
return -1;
}
else {
return first.val;
}
}
public boolean isEmpty() {
return first == null;
}
public void print(){
ListNode cur = first;
while (cur!=null){
System.out.print(cur.val+" ");
cur = cur.next;
}
System.out.println();
}
}
8.循环队列
还有一种队列叫做循环队列,通常使用数组实现
如何区分是空,还是满
定义一个head指向下标为0处,当index == arr.length-1则队列已经满,
每次释放元素,使head = (head+1)% arr.length, head == index的时候则队列已经空
9.双端队列:
两端都可以进队和出队的队列,Deque 是double ended queue” 的简称。可以从队尾进出,也可以从对头进出
Deque是一个接口,必须创建LinkedList的对象
但是在实际工程中,栈和队列都可以使用该接口。
//双端队列的线性实现
Deque<Integer> stack = new ArrayDeque<>();
//双端队列的链式实现
Deque<Integer> queue = new LinkedList<>();
10.面试题
1.用栈实现队列:. - 力扣(LeetCode)
2.用队列实现栈:. - 力扣(LeetCode)