先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:xhs1999xhs (备注Java)
正文
本专栏文章主要用于帮助Java使用者快速上手数据结构,刷算法题!
前言
自古以来数据结构界就分为九重天,据说冲破这九重天之后就可以去进攻算法界最终修炼最后成佬,受万人敬仰。
但是这谈何容易,因为每一重天都有神兽把守,想要冲破每一重天都必须收服守护的神兽才行。
守护九重天的神兽分别是:数组、字符串、栈、队列、链表、树、散列表、堆、图。可见他们的战斗力也是逐层增强的。想只凭靠自身的能力拿下他们谈何容易。
不过大家不必惊慌,我这里有一本上古秘籍《Java小子怒闯数据结构九重天》,里面有每一重天神兽的攻略。只要修炼者仔细钻研里面的每一篇,对九重天了如指掌之后,冲破这九重天也是易如反掌的。
今天为大家带来第五重天的攻略!
目录
1.🌀链表的基础知识
链表是一种线性表数据结构。它使用一组任意的存储单元(可以是连续的,也可以是不连续的),来存储一组具有相同类型的数据。
|
| |
简单来说链表是实现线性表的链式存储结构的基础。
链表是一种通过指针串联在一起的线性结构,每一个节点是由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。
节点情况如下:
数据域 | 指针域 |
---|---|
date | next |
上面的介绍都是单链表相关的,除了单链表我们还有双向链表,循环链表等。
双链表
双链表顾名思义就是比单链表高级了一点,一个双链表的结点在单链表的基础上又增加了一个指针,这个指针指向它的前一个结点
节点情况如下:
指针域 | 数据域 | 指针域 |
---|---|---|
prior | date | next |
循环链表
之前的链表都是条状的,循环链表是头尾相连了,就是将链表的尾部与头部连接起来。有因为条状链表有单链表与双链表之分,所以循环链表也有两种分别是:循环单链表与循环双链表
对于循环单链表我们一般设置尾指针这样操作效率会更高。
对于循环双链表我们头结点的prior结点指向最后一个节点,尾结点的next指针指向头结点,以形成循环双链表。
2.🌀Java实例化链表
想要实例化链表就得先创建一个链表的结构类,这个类代表的是每一个节点结构。
之前提到过每一个节点是由两部分组成,一个是数据域一个是指针域(存放指向下一个节点的指针),最后一个节点的指针域指向null(空指针的意思)。
所以链表节点结构定义为:
class ListNode {
int val; // 节点值
ListNode next; // 后继节点引用
ListNode(int x) {
val = x;
}
}
使用定义的这个链表结构我们可以自己构造一个链表如下:
// 实例化节点
ListNode n1 = new ListNode(4); // 节点 head
ListNode n2 = new ListNode(5);
ListNode n3 = new ListNode(1);
// 连接节点使之成为链表
n1.next = n2;
n2.next = n3;
n3.next = null;
我们构造出来的链表如下图:
3.🌀Java实现单链表
其中实现了Iterable
接口,提供了遍历方式。
import java.util.Iterator;
/\*\*
\* 链表的head是不可以动的
\* @param <T>
\*/
public class LinkList<T> implements Iterable<T>{
private Node head;//头结点,链表的head是不可以动的
private int N;//结点个数
//构造方法
public LinkList() {
this.head = new Node(null,null);
N = 0;
}
//结点内部类
private class Node{
//存储数据
T item;
//下一个结点
Node next;
public Node(T item,Node next) {
this.item = item;
this.next = next;
}
}
//清空链表
public void clear(){
head.item=null;
head.next=null;// 头节点next为null就是空链表
this.N=0;
}
//判断链表是否为空
public boolean isEmpty(){
return this.N==0;
}
//获取链表的长度
public int length(){
return this.N;
}
//读取链表第i位置的元素值并返回
public T get(int i){
//非法性检查
if(i<0 || i > this.N){
throw new RuntimeException("位置不合法");
}
// n也是指向头结点
Node n = head;
for(int index=0; index<i; index++){
n = n.next;
}
return n.item;
}
//往链表中插入数据t
public void insert(T t){
// head不可以移动,不然就无法在找到链表
// 定义一个临时的Node也指向head的指针就可以通过移动该指针就可以
Node n = head;
// 获取尾节点
while(true){
// 当刚好就一个节点时(头节点)
if(n.next == null){
break;
}
n = n.next;
}
//当为空表时,就可以插入
Node node = new Node(t, null);
n.next =node;
this.N ++;
}
//在第i位置上插入数据t
public void insert(T t,int i){
// 非法性检查
if(i < 0 || i > this.N){
throw new RuntimeException("插入位置非法");
}
Node pre = head;
for(int index=0;index <= i-1; index++){
pre = pre.next;
}
Node current = pre.next;
//先链接后面结点
Node newNode = new Node(t,null);
pre.next = newNode;
newNode.next = current;
this.N++;
}
//移除并返回第i位置的元素值
public T remove(int i){
// 非法性检查
if(i < 0 || i >this.N){
throw new RuntimeException("删除位置有误");
}
Node n =head;
for(int index=0;index <= i-1;index ++){
n = n.next;
}
//要删除的节点
Node curr = n.next;
n.next = curr.next;
this.N--;//结点个数减一
return curr.item;
}
//查找元素t在链表中第一次出现的位置
public int indexof(T t){
Node n = head;
for(int i = 0; n.next != null;i++){
n =n.next;
if(n.item.equals(t)){
return i;
}
}
return -1;
}
@Override
public Iterator iterator() {
return new Iterator() {
Node n =head;
@Override
public boolean hasNext() {
return n.next !=null;
}
@Override
public Object next() {
//下移一个指针
n = n.next;
return n.item;
}
};
}
}
补充一点:链表的赋值给新的链表后,两个链表是会相会影响的,说白了就是把地址赋值给它了,他们操作是同一块内存的同一个对象。
Node n = head;
把head赋值给n,现在对n操作也是会影响head的。
4.🌀链表进阶练习
我们可以申请两个指针,第一个指针叫 pre,最初是指向 null 的。
第二个指针 cur 指向 head,然后不断遍历 cur。
每次迭代到 cur,都将 cur 的 next 指向 pre,然后 pre 和 cur 前进一位。
都迭代完了(cur 变成 null 了),pre 就是最后一个节点了。
代码如下:
class Solution {
public ListNode reverseList(ListNode head) {
//申请节点,pre和 cur,pre指向null
ListNode pre = null;
ListNode cur = head;
ListNode tmp = null;
while(cur!=null) {
//记录当前节点的下一个节点
tmp = cur.next;
//然后将当前节点指向pre
cur.next = pre;
//pre和cur节点都前进一位
pre = cur;
cur = tmp;
}
return pre;
}
}
结语
恭喜你修炼到这里,你已经基本有了收服神兽链表的能力。神兽链表是我们到进攻算法界最重要的能力之一。大家不可懈怠。
感兴趣的修炼者可以关注下面公众号,会持续推送最新更新的!
持续更新中…
复习的面试资料
这些面试全部出自大厂面试真题和面试合集当中,小编已经为大家整理完毕(PDF版)
- 第一部分:Java基础-中级-高级
- 第二部分:开源框架(SSM:Spring+SpringMVC+MyBatis)
- 第三部分:性能调优(JVM+MySQL+Tomcat)
- 第四部分:分布式(限流:ZK+Nginx;缓存:Redis+MongoDB+Memcached;通讯:MQ+kafka)
- 第五部分:微服务(SpringBoot+SpringCloud+Dubbo)
- 第六部分:其他:并发编程+设计模式+数据结构与算法+网络
进阶学习笔记pdf
- Java架构进阶之架构筑基篇(Java基础+并发编程+JVM+MySQL+Tomcat+网络+数据结构与算法)
- Java架构进阶之开源框架篇(设计模式+Spring+SpringMVC+MyBatis)
- Java架构进阶之分布式架构篇 (限流(ZK/Nginx)+缓存(Redis/MongoDB/Memcached)+通讯(MQ/kafka))
- Java架构进阶之微服务架构篇(RPC+SpringBoot+SpringCloud+Dubbo+K8s)
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:xhs1999xhs (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-sc24r8mp-1713699374240)]
- Java架构进阶之微服务架构篇(RPC+SpringBoot+SpringCloud+Dubbo+K8s)
[外链图片转存中…(img-FTyXN5KO-1713699374240)]
[外链图片转存中…(img-Qaex7BoL-1713699374241)]
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:xhs1999xhs (备注Java)
[外链图片转存中…(img-xmQXJfDY-1713699374241)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!