1.什么是栈?
========
假如有一天你下课去小店,买了一条曼妥思准备回去上课的时候偷偷吃,你的同桌看见你的嘴巴一直在嚼,这时你小心翼翼的拿出一颗递给他,这时你就完成了一组出栈功能。如下图,右边就像你的曼妥思,你拿给同桌的肯定是从上往下的第一颗,也就是最上面的这颗糖,如果你下课还要给其他同学那你肯定是顺着往下继续给直到吃完为止。
**这种只能从一端进行元素的添加和删除的操作受限的线性表,我们就称之为栈。**当然这只是简易的单纯从数据结构的说法,我们的计算机内存中还有栈区,如果你想了解更多当然可以去自己了解。这里我只以最快的方式告诉你栈的逻辑结构
PS:栈的实现可以通过顺序表或链表实现,刚开始接触数据结构的同学不要思维定式,看着图里好像元素都靠在一起就像数组就得用顺序表,栈只要求我们只能在一端进行操作,保存数据的方式无论你选顺序表还是链表都是可以的。这里我更推荐使用链表实现,因为能用链表实现肯定也能用顺序表实现,我也以链表来演示。对于顺序表和链表不熟的同学推荐看看我的前三篇文章
2.栈的基本功能和结构
===========
public class Stack implements Iterable {
//记录首节点
private Node head;
//记录栈中元素个数
private int N;
private class Node{
public T item;
private Node next;
public Node(T item, Node next) {
this.item = item;
this.next = next;
}
}
public Stack(){
this.head=new Node(null,null);
this.N=0;
}
因为是以链表存储,同样需要一个内部类Node表示结点,栈成员属性有Node头结点head以及一个int类型变量N计算存储元素个数。构造方法中,new出一个stack(栈)时,需要初始化一个值为空(头结点不存储元素),next也为空,因为我们此时栈还是空的。千万别写成this.head=null,这是完全不同的,这样写代表根本没有头结点。
ps:在这我们要注意,因为栈的操作都是在一端,所以为了我们操作方便,我们的头结点是在进行操作的这一端,而且栈顶的元素不是头结点,而是我们头结点的next。有人说这样头结点不是好像一直随着压栈出栈的操作一直动吗?我把头结点放栈底那它不是不用动更好吗。但是我们数据结构追求的是效率呀,如果你的头结点是在栈低,那每次对栈顶进行操作,你都要通过遍历去找到栈顶的结点,这耗费的时间是巨大的。
public boolean isEmpty() | 判断栈是否为空 |
public int getLength() | 获取栈中元素的个数 |
public void push(T t) | 压栈(向栈顶放入元素) |
public T pop() | 出栈(拿出栈顶元素,并得到它的值) |
public T getHeadNext() | 获取栈顶元素(未拿出) |
public boolean contains(T t) | 判断栈中是否包含该元素 |
3.栈的基本功能详细代码实现
1. 判断栈是否为空
public boolean isEmpty(){
return N==0;
}
解析:因为我们有N统计栈中元素的个数,所以判断是否为空时,我们只需要返回N是否等于0即可。
2.获取栈中元素的个数
public int getLength(){
return N;
}
解析:同样是设计到元素的个数,需要获得栈中元素的个数,我们只需要返回N即可。感觉到这个N的好处了吗?
3.压栈(向栈顶放入元素)
/压栈
public void push(T t){
if(N==0){
Node newNode = new Node(t, null);
head.next=newNode;
}else {
//获取栈顶元素
Node a = head.next;
//创建新结点
Node newNode = new Node(t, a);
head.next = newNode;
}
N++;
}
解析:首先对于压栈操作,我们需要有两种情况区分,第一种情况此时栈中是否有元素,如果此时N==0,代表无元素,那我们需要new出一个新结点,保存T的值,然后将其放在head的next,因为是第一个进入的所以为栈顶元素。第二种情况此时栈中有元素,即head的next是存在结点的,因为压栈是在栈顶加入元素,这就需要我们在头结点和原栈顶元素之间插入新元素,所以我们先获取原栈顶元素a。new出的新结点保存T的值,同时next指向原栈顶元素,这时再让头结点不指向a转而指向新结点newNode,这样我们就成功压栈。最后不要忘了无论第一种还是第二种情况我们都需要让N加1。
最后
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长,自己不成体系的自学效果低效漫长且无助。
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,不论你是刚入门Java开发的新手,还是希望在技术上不断提升的资深开发者,这些资料都将为你打开新的学习之门!**
如果你觉得这些内容对你有帮助,需要这份全套学习资料的朋友可以戳我获取!!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!