一、链表的定义

【百度百科】链表(LinikedList)是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

链表最明显的好处就是,常规数组排列关联项目的方式可能不同于这些数据项目在记忆体或磁盘上顺序,数据的存取往往要在不同的排列顺序中转换。链表允许插入和移除表上任意位置上的节点,但是不允许随机存取。链表有很多种不同的类型:单向链表,双向链表以及循环链表。

二、各种链表实现示意图

三、链表的操作

1.单向链表

2.双向链表

3.循环链表

四、约瑟夫环问题实现

n 个人围成一个圆圈,首先第 k个人从 1 开始一个人一个人顺时针报数,报到第 m 个人,令其出列。然后再从下一 个人开始从 1 顺时针报数,报到第 m 个人,再令其出列,…,如此下去,求出列顺序。

这个问题可以转化成数据结构的循环链表问题。具体抽象为创建循环链表,输出链表,按照题意找到符合要求的那个结点并删除,循环删除的过程,直到循环链表只剩下一个元素,即为最后一个出队的元素。

/*** 总人数n:7 从第几个开始k:3 报数淘汰m:3* java 环形链表实现约瑟夫(Joseph)问题*/
public class JosephCycle {public static void main(String []args){CycleLink cl = new CycleLink();cl.setLen(7);cl.setK(3);cl.setM(3);cl.creatLink();cl.play();cl.show();}}class Node{int num;Node nextNode = null;public Node(int num){this.num = num;}
}class CycleLink{int len;int k ;int m ;Node firstNode = null;Node temp = null;public void setLen(int len){this.len = len;}public void setK(int k){this.k = k;}public void setM(int m){this.m =m;}//创建链表public void creatLink(){for(int i = 1; i <= len ; i++){// 处理首节点if(i==1){Node  nd= new Node(i);firstNode = nd;temp = nd;}else if(i == len){    //处理末节点Node nd = new Node(i);temp.nextNode = nd;temp = nd;temp.nextNode = firstNode;}else{Node nd = new Node(i);temp.nextNode = nd;temp = nd;}}}public void play(){temp = firstNode;// 先找到编号为k的节点for(int i = 1 ; i < k; i++){temp = temp.nextNode;}while(this.len !=1){//报数,找到m的上一个节点for(int j = 1 ;j < m-1; j++){temp = temp.nextNode;}//因为少报了  1  ,所以将下一个节点删除,并从下下一个节点重新开始报数System.out.println("要删除的节点: "+temp.nextNode.num);/*** 如果删除节点是firstNode,则将firstNode更新为下一个节点* 注意不能用编号判断,因为新的编号对应的节点有可能又被删除*/if(temp.nextNode==firstNode){firstNode = temp.nextNode.nextNode;}temp.nextNode = temp.nextNode.nextNode;temp = temp.nextNode;//this.show();this.len--;}}/*** 遍历链表打印整个链表*/public void show(){temp = firstNode;do{System.out.println(temp.num);temp = temp.nextNode;}while(temp != firstNode);}
}

运行结果:

要删除的节点: 5
要删除的节点: 1
要删除的节点: 4
要删除的节点: 2
要删除的节点: 7
要删除的节点: 3
6

五、Java中的链表类

LinkedList类的本质是是一个双向链表,也常可以当作堆栈、队列或这双端队列,所以在随机插入、随机删除时比ArrayList类的效率要高。特别是可以直接对集合的首部和尾部元素进行插入和删除操作,LinkedList提供了专门针对首尾元素的方法,

六、抽象数据类型(ADT)

是指一个数学模型及定义在该模型上的一组操作。它仅取决于其逻辑特征,而与计算机内部如何表示和实现无关。

栈和队列这两种数据结构,我们可以分别使用数组和链表来实现,比如栈,对于使用者只需要知道pop()和push()方法或其它方法的存在以及如何使用即可,使用者不需要知道我们是使用的数组或是链表来实现的。

这在我们Java语言中的接口设计理念是相通的。

七、链表的应用场景

1、单向链接

单向链表适用于只从一端单向访问的场合,这种场合一般来说:

  1. 删除时,只适合删除第一个元素;
  2. 添加时,只直接添加到最后一个元素的后面或者添加到第一个元素的前面;
  3. 属于单向迭代器,只能从一个方向走到头(只支持前进或后退,取决于实现),查找效率极差。不适合大量查询的场合。

这种典型的应用场合是各类缓冲池和栈的实现。

2、双向链表

双向链表相比单向链表,拥有前向和后向两个指针地址,所以适合以下场合:

  1. 删除时,可以删除任意元素,而只需要极小的开销;
  2. 添加时,当知道它的前一个或后一个位置的元素时,只需要极小的开销。
  3. 属于双向迭代器,可以从头走到尾或从尾走到头,但同样查找时需要遍历,效率与单向链表无改善,不适合大量查询的场合。

这种典型的应用场景是各种不需要排序的数据列表管理。

八、总结

上面我们讲了各种链表,每个链表都包括一个LinikedList对象和许多Node对象,LinkedList对象通常包含头和尾节点的引用,分别指向链表的第一个节点和最后一个节点。而每个节点对象通常包含数据部分data,以及对上一个节点的引用prev和下一个节点的引用next,只有下一个节点的引用称为单向链表,两个都有的称为双向链表。next值为null则说明是链表的结尾,如果想找到某个节点,我们必须从第一个节点开始遍历,不断通过next找到下一个节点,直到找到所需要的。栈和队列都是ADT,可以用数组来实现,也可以用链表实现。


我的微信公众号:架构真经(id:gentoo666),分享Java干货,高并发编程,热门技术教程,微服务及分布式技术,架构设计,区块链技术,人工智能,大数据,Java面试题,以及前沿热门资讯等。每日更新哦!

参考文章:

  1. https://www.cnblogs.com/ysocean/p/7928988.html
  2. https://blog.csdn.net/baidu_37181928/article/details/80731350
  3. https://blog.csdn.net/qq_34478594/article/details/80351017
  4. https://www.cnblogs.com/lightandtruth/p/9468278.html

程序员的进阶课-架构师之路(6)-链表相关推荐

  1. 程序员的进阶课-架构师之路(17)-堆

    我们来介绍另外一种数据结构-堆,注意这里的堆和我们Java语言,C++语言等编程语言在内存中的"堆"是不一样的,这里的堆是一种树,由它实现的优先级队列的插入和删除的时间复杂度都为O ...

  2. 根据id获取多维数组路径_程序员的进阶课-架构师之路(2)-数组

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/ ...

  3. 程序员的进阶课-架构师之路(18)-图

    一.图的定义 在计算机科学中,图(Graphics)是由顶点集合(Vertex)及顶点间的关系(边)集合(Edge)组成的一种数据结构,这些顶点通过一系列边结对(连接).顶点用圆圈表示,边就是这些圆圈 ...

  4. 程序员的进阶课-架构师之路(7)-树的概念

    接下来我们将会介绍另外一种数据结构--树.二叉树是树这种数据结构的一员,后面我们还会介绍红黑树,2-3-4树等数据结构.那么为什么要使用树?它有什么优点? 前面我们介绍数组的数据结构,我们知道对于有序 ...

  5. 程序员的进阶课-架构师之路(5)-队列

    一.队列的定义 队列(queue)是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作,和栈一样,队列是一种操作受限制的线性表.进行插入操 ...

  6. 程序员的进阶课-架构师之路(4)-栈

    一.栈的定义 [百度百科]栈作为一种数据结构,是一种只能在一端进行插入和删除操作的特殊线性表.它按照先进后出的原则存储数据,先进入的数据被压入栈底,最后的数据在栈顶,需要读数据的时候从栈顶开始弹出数据 ...

  7. 程序员的进阶课-架构师之路(3)-线性表

    一.线性表的定义 [百度百科]线性表是最基本.最简单.也是最常用的一种数据结构.线性表(linear list)是数据结构的一种,一个线性表是n个具有相同特性的数据元素的有限序列. 线性表中数据元素之 ...

  8. 程序员的进阶课-架构师之路(2)-数组

    从这一节开始,我们就要正式进去数据结构的世界了,那么第一个是什么呢,就是我们的数组. 在我想写数组的时候,我的第一印象是去看它的源码,很可惜,数组的实现太特殊了,找了很久,我没有找到它的源码,带着这样 ...

  9. 程序员的进阶课-架构师之路(1)-数据结构与算法简介

    现在市面上的数据结构与算法的教程也都不少,但有两个问题,第一是泛泛而谈,第二是基本都是c语言实现,而java作为第一主流语言,理应有它自己的独到之处.这也是我写这些博客的初衷,我会讲解java实现的数 ...

  10. 二叉树为空意味着二叉树_程序员的进阶课-架构师之路(8)-二叉树

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/m0_37609579/article/ ...

最新文章

  1. ON REG EXPRESSION.SYNTAX
  2. Struts2配置文件中传递参数的一个小问题
  3. Nacos-服务多级存储模型
  4. K8S——单master节点和基于单master节点的双master节点二进制部署(本机实验,防止卡顿,所以多master就不做3台了)
  5. sql插入临时表数据的方法
  6. java 异常补偿解决_第三方接口调用异常补偿机制实现实例记录
  7. delphi控件切图界面闪烁_先本设计教你跳过UI小程序的七个坑
  8. SSE指令集学习之旅(一)
  9. .net async/await 异步等待的数种情况
  10. 普通队列(数组实现)
  11. VS2012写的程序在VS2010打开时显示当前版本不兼容
  12. #pragma pack与sizeof union
  13. 黄淮学院计算机专业录取分数线2019,黄淮学院2020年录取分数线(附2017-2020年分数线)...
  14. JVM学习-深入理解Java虚拟机代码实践问题
  15. 1.4多媒体技术的发展历史
  16. 支持VS2017的vax插件VA_X_Setup2210
  17. 能否构成三角形的条件代码_初中阶段数学三角形相关知识点汇总,超全
  18. 电脑桌面显示不全设置方法
  19. excel软件做折线图
  20. 腾讯和360之争所折射出的下作

热门文章

  1. 搜索框中“请输入搜索keyword”
  2. js获取字符串的字节数
  3. 获得显示器设置的分辨率
  4. LeetCode 59. 螺旋矩阵 II
  5. leetcode51. N皇后
  6. python 字符串%和format_Python必懂知识点,格式化字符串,到底用.format还是%
  7. goalnd 分支合并完出现两个箭头
  8. linux性能监控sar命令详解
  9. python设计模式19-观察者模式
  10. vc范例-操作mysql数据库_VC范例-操作MySQL数据库