14天阅读挑战赛
努力是为了不平庸~
算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!欢迎记录下你的那些努力时刻(算法学习知识点/算法题解/遇到的算法bug/等等),在分享的同时加深对于算法的理解,同时吸收他人的奇思妙想,一起见证技术er的成长~
文章目录
算法知识点
链表的引入
数组的缺陷
:
- 大小是有限的
- 插入的效率是非常低的
为了解决
上述问题(插入和删除的线性开销
),创建
了一个新的数据结构
:
链表
- 链表是
不连续存储的
插入删除都是O(1)
- 代价是
不能够快速访问
具体元素。
链表的结构
链表有一个个结点组成,结点包含两部分
- 数据
- 引用
链表结点的定义
class Link{
public int value;//数据,类型不只可以为int,也可以是对象或泛型
public Link next;
}
可以将链表结点看作是一个对象
一个问题:Link类中包含了一个LInk类型,那怎么知道占用了多大的内存空间
?
表面上看,Link内存空间=value+next,但是next是Link,相当于是?=int+ ?,这是求不出来的。实际上是对引用的运用
,next是Link的引用类型大小是确定的
,所以Link是可以计算大小的。
知识小贴士:
有关引用和基本数据类型的介绍
- 基本数据类型,在Java中基本数据类型的值是实实在在的
数值
,例如 double a=45.00,实在内存里创建了一个空间将45.00放入其中 - 引用,某个对象的参照数值,计算机内存中的
对象地址
,只要是告诉你对象在哪里。在计算机中,所有引用不管指向谁,大小都是一样的。
链表的具体实现–单链表
上述定义中描述的就是点链表
单链表的基本运用
:
删除
一个结点
/*
LinkNode pre 前一个结点
LinkNode n 要删除的结点
LinkNode next 后一个结点
删除节点操作
*/
pre.next=next;
删除一个结点首先要拿到要删除结点的前一个结点
和后一个结点
,然后直接将前一个节点的引用指向
后一个结点,有需要的话(C++),将删除的结点的内存释放掉。
插入
一个结点,和删除很相似(反向操作
),找到要插入结点的位置,然后找到要插入节点的前一个和后一个结点,将前一个结点的引用指向要插入的结点,然后要插入的结点指向后一个结点。像链表的构造(头插法和尾插法)都是介于结点的插入来完成。
/*
LinkNode pre 前一个结点
LinkNode n 要插入的结点
LinkNode next 后一个结点
插入节点操作
*/
pre.next=n;
n.next=next;
总的来说链表的各种操作都是基于改变引用的指向
来完成。
单链表插入删除的特例
如果像起始结点插入删除一个节点
,这会改变链表的起始端,上面的方法明显不再适用
解决:
在链表的起始结点之前增加一个表头header结点
,这是一个标志结点,一个假想的结点,他的目的是为了避免这种特殊情况的发生
。(在链表的最后结点插入和删除可以增加一个表尾结点
)
- 另一种解决办法,在
代码中特殊判断
,这无疑会增加代码的复杂度
链表的具体实现–双端链表
链表的具体实现–循环链表
作者还在积极码字中…