JavaSE进阶(七)——手写链表
前言
本篇笔记单纯炫技,其中***可能会有一些思想和逻辑***,能吃到多少就是你们自己的事了,录视频授课也需要至少两个课时(可能还不够),众所周知,我懒!所以……嘿嘿。
链表相关介绍
要点
- 链表的头结点(第一个元素是不存放元素值的,一般只用来当做链表的开始);
- 链表使通过引用来指向的,C语言中可以理解为指针。但是与指针不同的是我们无法对引用做加减法运算来移动指针的位置,所以只能通过逻辑关系来设定引用的指向;
- 本次手写的链表中一定要注意理解空指针异常(数组下标越界异常)的原因。
代码
public class Linker {
// 表示默认值或者没有找到对应元素时的标志
private final int FLAG = -9999;
// 元素值
private int value;
// 定义链表间的指向关系(引用)
private Linker next;
public Linker() {
this.value = FLAG;
}
public Linker(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public void setValue(int value) {
this.value = value;
}
public Linker getNext() {
return next;
}
public void setNext(Linker next) {
this.next = next;
}
// 添加元素
public void add(int value){
Linker linker = new Linker(value);
// linker.value = value;
linker.next = this.next;
this.next = linker;
}
// 根据索引查找元素值
public int get(int index){
int i = 0;
// 定义一个引用来操作链表,直接使用this引用会破坏链表结构
// 头结点不存值,所以我们没必要在操作的时候遍历头结点
Linker temp = this.next;
while(temp != null){
if (i != index){
i ++;
// 判断当前节点后是否有节点,如果有则引用后移
if (temp.next != null){
temp = temp.next;
}
continue;
}
if (i == index){
return temp.value;
}
i ++;
}
return FLAG;
}
// 根据元素值查找链表中第一次出现的元素位置(索引)
public int getByValue(int value){
int i = 0;
Linker temp = this.next;
while(temp != null){
if (temp.value != value){
i ++;
if (temp.next != null){
temp = temp.next;
}
continue;
}
if (temp.value == value){
return i;
}
i ++;
}
return FLAG;
}
// 遍历全部
public void findAll(){
int i = 0;
Linker temp = this.next;
while (temp != null){
System.out.println(temp.value);
temp = temp.next;
}
}
// 根据索引修改值
public int set(int index, int newValue){
int i = 0;
Linker temp = this.next;
while(temp != null){
if (i != index){
i ++;
if (temp.next != null){
temp = temp.next;
}
continue;
}
if (i == index){
temp.value = newValue;
return 1;
}
i ++;
}
return 0;
}
// 按照索引删除元素
public boolean remove(int index){
int i = 0;
/*
删除操作必须有两个引用分别指向相邻两个元素。
因为在删除这个元素的时候必须将当前元素的下一个元素与当前元素的上一个元素相连,否则链表会断掉
*/
Linker prex = this;
Linker temp = this.next;
while(temp != null){
if (i != index){
i ++;
prex = prex.next;
temp = temp.next;
continue;
}
if (i == index){
prex.next = temp.next;
temp.next = null;
return true;
}
i ++;
}
if(temp == null){
System.out.println("数组下标越界");
}
return false;
}
// 输出链表长度
public int size(){
int count = 0;
Linker temp = this;
while (temp.next != null){
temp = temp.next;
count ++;
}
return count;
}
}
总结
个人觉得这个链表的代码比较基础,努努力还是可以看懂的。而且本篇笔记中手写链表的功能也比较简单,比如排序什么的就没写(主要是我懒),如果想写排序的同学可以参考删除模块的引用变化来看基本逻辑(不难,但是有点费脑子),至于排序的方法可以采用很多,建议大家从最简单的冒泡开始,逐渐加深难度。
本来在遍历的时候想写迭代来着,但是假如太多东西可能对初学者不友好(绝对不是因为我懒),所以使用普通循环的方式来完成。
感觉不理解链表的同学可以去看看数据结构。初学者推荐《大话数据结构》这本书,更加清晰直观的学习数据结构。但是这本书仅仅让你了解数据结构,勉强能入门,剩下的就需要难度大一些的教程,推荐严蔚敏老师的《数据结构》,最好看第一版,同时去找严蔚敏老师的数据结构教学视频(别管画质,你们是去听课的,能看清课件、听清讲课就行),如果只能听出严老师在读PPT的同学建议重新学习,别去评论区开喷,反正我学到东西了。如果您比我懂得多也没必要看我的博客不是?
话说到这,数据结构和编程的思维逻辑非一朝一夕,大家努力,加油!