1.栈(Stack)
1.1栈的基本概念:
栈:一种特殊的线性表,其只允许在固定的一端插入和删除元素的操作。进行数据插入和删除操作的一端称为栈顶,另一端称为栈底。栈中的数据元素遵循的是后进先出(Last In First Out)的原则。
压栈:栈的插入操作叫做进栈/出栈/入栈,入数据在栈顶。
出栈:栈的删除操作叫做出栈,出数据在栈顶。
1.2入栈与出栈示意图
1.2.1入栈示意图:
1.2.2出栈示意图:
1.3实现(栈)
1.3.1利用顺序表来实现栈(使用尾插操作表示“入栈”,使用尾删操作表示“出栈”,根据下标来获取元素的操作表示“取栈顶元素”操作)
//标准库中也有一个“Stack”这样的类,为了区别开,咱们别和标准库重合
public class MyStack {
private int[] data=new int[100];
private int size=0;
//基本操作
//1.入栈
public void push(int val){
if(size>=data.length){
//在这里也可以进行扩容
return;
}
data[size]=val;
size++;
}
//2.出栈,返回值就是被出栈了的那个元素
public Integer pop(){
if(size==0){
return null;
}
//栈顶元素就是最后一个元素
int ret=data[size-1];
size--;
return ret;
}
//3.取栈顶元素
public Integer peek(){
if(size==0){
return null;
}
return data[size-1];
}
}
1.3.2:利用链表来实现栈(使用“头插操作”表示入栈,使用头删操作表示“出栈”,直接取头结点,表示取“栈顶元素”)
//使用链表来实现栈
class Node{
int val;
Node next;
public Node(int val){
this.val=val;
}
}
public class MyStack2 {
private Node head=null;
//核心操作
//1.入栈
public void push(int val){
Node newNode=new Node(val);
//把新结点进行头插
if(head==null){
head=newNode;
return;
}
newNode.next=head;
head=newNode;
}
//出栈
public Integer pop(){
//进行头删
if(head==null){
return null;
}
if(head.next==null){
int ret=head.val;
head=null;
return ret;
}
int ret=head.val;
head=head.next;
return ret;
}
//3.取栈顶元素
public Integer peek(){
if(head==null) {
return null;
}
return head.val;
}
}
``**2.队列**
2.1队列的基本概念
**队列**:只允许一端进行插入数据操作,在另外一端进行删除数据操作的特殊线性表,队列具有**先进先出**(First In First Out)
**入队列**:进行插入操作的一端称为队尾(Tail/Rear)
**出队列**:进行删除操作的一端称为队头(Head/Front)
2.2实现
2.2.1使用链表来实现队列(使用尾插表示入队列(插入一端的操作称为队尾),使用头删的操作表示出队列(进行删除的一端称为队头),直接获取头结点,就是取队首元素)
```java
//使用链表实现队列
public class MyQueue {
static class Node{
int val;
Node next;
public Node(int val){
this.val=val;
}
}
//创建一个链表的头结点
//为了方便的进行尾插
private Node head=null;
private Node tail=null;
//队列的核心操作也是3个
//1.入队列
//表示插入成功或者插入失败
//也是为了和标准库中的offer接口看起
public boolean offer(int val){
Node newNode=new Node(val);
//插入到链表的尾部
if(head==null){
head=newNode;
tail=newNode;
return true;
}
tail.next=newNode;
tail=tail.next;
return true;
}
//2.出队列
public Integer poll(){
if(head==null){
return null;
}
int ret=head.val;
if(head.next==null){
head=null;
return ret;
}
head=head.next;
return ret;
}
//取队首元素
public Integer peek(){
if(head==null){
return null;
}
return head.val;
}
}
2.2.2使用顺序表来实现队列
//使用数组来实现队列
//就稍微复杂一点,单纯使用顺序表,势必会涉及头插
public class MyQueue2 {
//队列的有效区间为[head,tail)
private int [] data=new int [100];
private int head=0;
private int tail=0;
private int size=0;
//核心操作
//1.入队列
public boolean offer(int val){
if(size==data.length){
//队列满了,此处可以实现扩容逻辑
return false;
}
//把新元素放到tail对应的下标上
data[tail]=val;
//自增tail
tail++;
//一旦tail到达了数组的末尾,就让tail从头开始
if(tail==data.length){
tail=0;
}
//这个代码也可以写作
tail=tail%data.length;
//更新size的值
size++;
return true;
}
//2.出队列
public Integer poll(){
if(size==0){
return null;
}
int ret=data[head];
//更新head的位置
head++;
if(head==data.length){
head=0;
}
size--;
return ret;
}
//取队首元素
public Integer peek(){
if(size==0){
return null;
}
return data[head];
}
}