数据结构与算法系列2 线性表 链表的分类+使用java实现链表+链表源码详解
数据结构与算法系列2.2 线性表
什么是链表?
链表是一种物理存储单元上非连续,非顺序的存储结构,数据元素的逻辑顺序是通过链表的链接次序实现的一系列节点组成,节点可以在运行时动态生成,每个节点包括两个部分,一个是村粗数据元素的数据域,一个是存储指针的指针域,相比于线性表顺序结构,操作复杂。由于不必须按照顺序存储,链表在插入的时候可以达到o(1)的复杂读,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。
使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。但是链表失去了数组随机读取的优点,同时链表由于增加了结点的指针域,空间开销比较大。链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。链表可以在多种编程语言中实现。像Lisp和Scheme这样的语言的内建数据类型中就包含了链表的存取和操作。程序语言或面向对象语言,如C,C++和Java依靠易变工具来生成链表。
啥是单向链表和双向链表及循环链表?
单向链表
其特点是链表的连接方向是单向的,对链表的访问要通过顺序从头部开始,链表是使用指针进行构造的链表,又称为结点列表,因为链表是由一个个结点组装起来的;其中每个结点都有指针成员变量指向列表中的下一个结点;
因为单向链表的每个节点只包含两部分,一部分存放数据变量的data,另一部分是指向下一节点的next指针

双向链表
双向链表和单向链表的差别不是很大,只是比单向链表多了一个指向直接前驱节点的指针,这样使得,可以从双向链表的任一一个节点开始,都可以方便的访问它的前驱节点和后继节点

循环链表
循环链表是另一种形式的链式存贮结构。它的特点是表中最后一个结点的指针域指向头结点,整个链表形成一个环。

单向链表的代码实现,这里只讲几个常用到的方法
int size();元素的数量
boolean isEmpty();是否为空
boolean contains(E element); 判断是否包含某个元素
void add(E element) ;添加元素到最后
E get(int index);返回index对应位置的元素
E set(int index,E element);往index位置添加元素
void add(int index,E element);往index位置添加元素
E remove(int index); 删除index位置对应的元素
int indexOf(E element); 查看元素的位置
void clear();清除所有元素

成员变量
//头节点
private Node<E> first;
// 元素的数量
protected int size;
将节点定义为内部类
public static class Node<E>{
//元素
E element;
//指针
Node<E> next;
//构造函数
public Node(E element,Node<E> next){
this.element=element;
this.next=next;
}
}
清空所有元素 clear()
public void clear() {
size=0;
first=null;
}
将fist设置为null即可,因为当fist与节点断开连接后,该链表就会被自动回收,不必当心内存浪费
添加元素 add(int index,E element)
public void add(int index, E element) {
//检查范围是否合法
rangeCheck(index);
//如果在索引为零的地方插入
if (index==0){
first=new Node<>(element,first);
}else{
//查找插入节点的前一个节点
Node<E> prev=node(index-1);
prev.next=new Node<>(element,prev.next);
}
size++;
}
以图演示

要在1——2之间插入一个新的节点3,则要将1的指针指向3,再将3的指针指向2

在末尾添加元素
public void add(E element) {
add(size, element);
}
直接调用上一个方法即可
获得指定节点位置的元素node(int index)
//获取index位置对应的节点对象
private Node<E> node(int index){
rangeCheck(index);
Node<E> node=first;
for (int i = 0; i < index; i++) {
node=node.next;
}
return node;
}
删除元素remove(int index)
public E remove(int index) {
//检查插入位置是否合理
rangeCheck(index);
///查找要移除元素的前一个元素
//如果为零
Node<E> node = first;
if (index==0){
first=first.next;
}else{
Node<E> prev = node(index - 1);
node=prev.next;
prev.next=node.next;
}
size--;
return node.element;
}
图解

比如我要将3这个节点移除,那么我就要将1的指针指向2,即3指针指向的的节点

获取第index位置的元素
@Override
public E get(int index) {
return node(index).element;
}
设置第index位置的元素
@Override
public E set(int index, E element) {
Node<E> node = node(index);
E old= node.element;
node.element=element;
return old;
}
以上就是java链表的源码解析,我也会在我的博客上经常更新一些算法类的题目, 喜欢的也可以关注我,创作不易,觉得有帮助的可以点赞收藏关注

数据结构与算法系列2 线性表 链表的分类+使用java实现链表+链表源码详解的更多相关文章
- JavaScript 数据结构与算法之美 - 线性表(数组、栈、队列、链表)
前言 基础知识就像是一座大楼的地基,它决定了我们的技术高度. 我们应该多掌握一些可移值的技术或者再过十几年应该都不会过时的技术,数据结构与算法就是其中之一. 栈.队列.链表.堆 是数据结构与算法中的基 ...
- 数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解
数据结构与算法系列2 线性表 使用java实现动态数组+ArrayList源码详解 对数组有不了解的可以先看看我的另一篇文章,那篇文章对数组有很多详细的解析,而本篇文章则着重讲动态数组,另一篇文章链接 ...
- javascript实现数据结构与算法系列:线性表的静态单链表存储结构
有时可借用一维数组来描述线性链表,这就是线性表的静态单链表存储结构. 在静态链表中,数组的一个分量表示一个结点,同时用游标(cur)代替指针指示结点在数组中的相对位置.数组的第0分量可看成头结点,其指 ...
- Java源码详解系列(十)--全面分析mybatis的使用、源码和代码生成器(总计5篇博客)
简介 Mybatis 是一个持久层框架,它对 JDBC 进行了高级封装,使我们的代码中不会出现任何的 JDBC 代码,另外,它还通过 xml 或注解的方式将 sql 从 DAO/Repository ...
- 源码详解系列(六) ------ 全面讲解druid的使用和源码
简介 druid是用于创建和管理连接,利用"池"的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制.连接可靠性测试.连接泄露控制.缓存语句等功能,另外,druid还扩展 ...
- 源码详解系列(七) ------ 全面讲解logback的使用和源码
什么是logback logback 用于日志记录,可以将日志输出到控制台.文件.数据库和邮件等,相比其它所有的日志系统,logback 更快并且更小,包含了许多独特并且有用的特性. logback ...
- 源码详解系列(八) ------ 全面讲解HikariCP的使用和源码
简介 HikariCP 是用于创建和管理连接,利用"池"的方式复用连接减少资源开销,和其他数据源一样,也具有连接数控制.连接可靠性测试.连接泄露控制.缓存语句等功能,另外,和 dr ...
- Mybatis源码详解系列(四)--你不知道的Mybatis用法和细节
简介 这是 Mybatis 系列博客的第四篇,我本来打算详细讲解 mybatis 的配置.映射器.动态 sql 等,但Mybatis官方中文文档对这部分内容的介绍已经足够详细了,有需要的可以直接参考. ...
- 套用GGTalk做项目的经验总结——GGTalk源码详解系列(一)
坦白讲,我们公司其实没啥技术实力,之所以还能不断接到各种项目,全凭我们老板神通广大!要知道他每次的饭局上可都是些什么人物! 但是项目接下一大把,就凭咱哥儿几个的水平,想要独立自主.保质保量保期地一个个 ...
随机推荐
- Linux之iptables原理详解
目录: 一.netfilter与iptables 二.filter.nat.mangle等规则表 三.INPUT.FORWARD等规则链和规则 四.Linux数据包路由原理 五.iptables编写规 ...
- SpringBoot+Dynamic多数据源动态切换
最近做了个小模块,需求就是项目同时读取三个数据库,操作数据.并不是分库分表,只用定时跑,不需要对外提供接口. 技术选型:SpringBoot + Mybatis Plus(Mybatis) + Dyn ...
- 笨办法学python3练习代码ex18.py
#命名.变量.代码.函数 #this one is like your scripts with argv def print_two(*args): arg1, arg2 = args #将参数解包 ...
- 029_go语言中的非阻塞通道
代码演示 package main import "fmt" func main() { messages := make(chan string) signals := make ...
- Linux学习笔记之linux软件包安装以及源的替换
先是软件源的替换,在刚安装的Ubuntu中会配有原先的软件源,所以如果要替换时,可在网上找与自己ubuntu相对应的软件源,比如我的ubuntu版本为12.04,所以我得找到相对应能够适用Ubuntu ...
- CSS漂亮盒子(下)
4.多重背景 CSS支持一个元素设置多个背景图片. 每个背景属性有相应的多值语法,多个值由逗号分隔. .multi-bg-shorthand { width: 300px; height: 200px ...
- Docker 启动 Nginx
Docker 启动 Nginx 拉取镜像 docker pull nginx:1.17.9 启动步骤 # 创建 nginx 目录 mkdir -p /usr/local/nginx && ...
- windows系统下python setup.py install ---出现cl问题,cpp_extension.py:237: UserWarning: Error checking compiler version for cl: 'utf-8' codec can't decode byte 0xd3 in position 0: invalid continuation byte
将cpp_extension.py文件中的 原始的是 compiler_info.decode() try: if sys.platform.startswith('linux'): minimu ...
- .NET Core Web APi大文件分片上传研究
前言 前两天发表利用FormData进行文件上传,然后有人问要是大文件几个G上传怎么搞,常见的不就是分片再搞下断点续传,动动手差不多也能搞出来,只不过要深入的话,考虑的东西还是很多.由于断点续传之前写 ...
- C#LeetCode刷题之#202-快乐数(Happy Number)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3856 访问. 编写一个算法来判断一个数是不是"快乐数& ...