热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

java单链表和双_Java链表,单链表和双链表

Java-链表1、什么是链表?2、链表的特点是什么?3、链表的实现原理?4、如何自己写出一个链表?1、什么是链表࿱

Java-链表

1、什么是链表?

2、链表的特点是什么?

3、链表的实现原理?

4、如何自己写出一个链表?

1、什么是链表?

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。

每一个链表都包含多个节点,节点又包含两个部分,一个是数据域(储存节点含有的信息),一个是引用域(储存下一个节点或者上一个节点的地址)。

链表的理解示意图

9b6aac6e00117f24421871600cf68a1f.png

2、链表的特点是什么?

获取数据麻烦,需要遍历查找,比数组慢

方便插入、删除

3、链表的实现原理

创建一个节点类,其中节点类包含两个部分,第一个是数据域(你到时候要往节点里面储存的信息),第二个是引用域(相当于指针,单向链表有一个指针,指向下一个节点;双向链表有两个指针,分别指向下一个和上一个节点)

创建一个链表类,其中链表类包含三个属性:头结点、尾节点和大小,方法包含添加、删除、插入等等方法。

单向链表的节点类:

1 public class Node {

2 public Object data;

3 public Node next;

4

5 public Node(Object e){

6 this.data = e;

7 }

8 }

双向链表的节点类:

1 public class Node {

2 public Object e;

3 public Node next;

4 public Node pre;

5 public Node(){

6

7 }

8 public Node(Object e){

9 this.e = e;

10 next = null;

11 pre = null;

12 }

13 }

4、如何自己写出一个链表?

代码如下(以双向链表为例,有详细的注释,单向链表同理):

首先创建了一个节点类

1 package MutuLink;

2

3 public class Node {

4 public Object e;

5 public Node next;

6 public Node pre;

7 public Node(){

8

9 }

10 public Node(Object e){

11 this.e = e;

12 next = null;

13 pre = null;

14 }

15 }

然后创建了一个链表类

1 package MutuLink;

2

3 public class MyList {

4 private Node head;

5 private Node tail;

6 private int size = 0;

7

8 public MyList() {

9 head = new Node();

10 tail = new Node();

11 head.next =null;

12 tail.pre = null;

13 }

14

15 public boolean empty() {

16 if (head.next == null)

17 return true;

18 return false;

19 }

20 //找到所找下标节点的前一个节点

21 public Node findpre(int index){

22 Node rnode = head;

23 int dex = -1;

24 while(rnode.next != null){

25 //找到了插入节点的上一个节点

26 if( dex== index - 1){

27 return rnode;

28 }

29 rnode = rnode.next;

30 dex++;

31 }

32 return null;

33 }

34 public Node findthis(int index){

35 Node rnode = head;

36 //把rnode想象为指针,dex为指向的下标,这个地方很容易错,因为当指向最后一个节点时没有判断IF就跳出循环了

37 int dex = -1;

38 while(rnode.next != null){

39 if(dex == index)

40 return rnode;

41 rnode = rnode.next;

42 dex++;

43 }

44 if(dex == size - 1){

45 return rnode;

46 }

47 // Node test = new Node(new Students("haha",1,2));

48 return null;

49 }

50

51 // 往链表末尾加入节点

52 public void add(Object e) {

53 Node node = new Node(e);

54 Node rnode = head;

55 //如果是空链表的话插入一个节点,这个节点的pre不能指向上一个节点,必须指空

56 if (this.empty()) {

57 rnode.next = node;

58 rnode.next.pre = null;

59 tail.pre = node;

60 size++;

61 } else {

62 while (rnode.next != null)

63 rnode = rnode.next;

64 rnode.next = node;

65 node.pre = rnode;

66 tail.pre = node;

67 size++;

68 }

69 }

70 //往链表的某一个标插入一个节点

71 public boolean add(int index,Object e){

72 if(index <0||index>&#61;size)

73 return false;

74 Node node &#61; new Node(e);

75 Node prenode &#61; this.findpre(index);

76 node.next &#61; prenode.next;

77 prenode.next.pre &#61; node;

78 prenode.next &#61; node;

79 node.pre &#61; prenode;

80 size&#43;&#43;;

81 return true;

82 }

83 public boolean add(int index,MyList myl){

84 if(index <0 || index >&#61; size)

85 return false;

86 Node prenode &#61; this.findpre(index);

87 // myl.tail.pre.next &#61; prenode.next;

88 // prenode.pre &#61; myl.tail.pre;

89 // tail.pre &#61; null;

90 // prenode.next &#61; myl.head.next;

91 // myl.head.next.pre &#61; prenode;

92 // head.next &#61; null;

93 myl.tail.pre.next &#61; prenode.next;

94 prenode.next.pre &#61; myl.tail.pre.pre;

95 myl.head.next.pre &#61; prenode.pre;

96 prenode.next &#61; myl.head.next;

97 myl.head &#61; null;

98 myl.tail &#61; null;

99 size&#43;&#61;myl.size;

100 return true;

101 }

102

103 public Object remove(int index){

104 Object ob&#61; this.get(index);

105 if(index <0 || index >&#61; size)

106 return null;

107 //特殊情况&#xff0c;当移除节点是最后一个节点的时候

108 //较为复杂通过画图来写代码

109 if(index &#61;&#61; size - 1){

110 Node prenode &#61; this.findpre(index);

111 this.tail.pre &#61; this.tail.pre.pre;

112 this.tail.pre.next.pre &#61; null;

113 this.tail.pre.next &#61;null;

114 size--;

115 return ob;

116 }

117 //比较复杂&#xff0c;通过画图解决

118 else{

119 Node prenode &#61; this.findpre(index);

120 prenode.next &#61; prenode.next.next;

121 prenode.next.pre.next &#61; null;

122 prenode.next.pre &#61; prenode.next.pre.pre;

123 size--;

124 return ob;

125 }

126 }

127

128

129 public Object get(int index){

130 Node thisnode &#61; this.findthis(index);

131 return thisnode.e;

132 }

133 public int size(){

134 return size;

135 }

136 }

最后测试

1 package MutuLink;

2

3 import java.util.Random;

4

5 public class manage {

6 public static void main(String[] args) {

7 String name &#61; "";

8 int credit;

9 int age;

10 int size;

11 MyList myl &#61; new MyList();

12 Random random &#61; new Random();

13 size &#61; random.nextInt(5) &#43; 1;

14 for (int i &#61; 0; i

15 credit &#61; random.nextInt(5);

16 age &#61; random.nextInt(5) &#43; 18;

17 for (int j &#61; 0; j <4; j&#43;&#43;) {

18 name &#43;&#61; (char) (random.nextInt(26) &#43; 97);

19 }

20 Students stu &#61; new Students(name, credit, age);

21 myl.add(stu);

22 name &#61; "";

23 }

24

25 System.out.println("Size of myl1 is "&#43; myl.size());

26 for(int i &#61; 0; i

27 Students stu2 &#61; (Students) myl.get(i);

28 stu2.show();

29 }

30 // //测试能否在链表末尾加入节点(成功)

31 // for(int i &#61; 0; i

32 // Students stu2 &#61; (Students) myl.get(i);

33 // stu2.show();

34 // }

35 // //测试能否通过下标加入一个节点(成功)

36 // Students stu3 &#61; new Students("cyt",5,18);

37 // myl.add(1, stu3);

38 // System.out.println("Size is "&#43; myl.size());

39 // for(int i &#61; 0; i

40 // Students stu2 &#61; (Students) myl.get(i);

41 // stu2.show();

42 // }

43

44 MyList myl2 &#61; new MyList();

45 size &#61; random.nextInt(5) &#43; 1;

46 for (int i &#61; 0; i

47 credit &#61; random.nextInt(5);

48 age &#61; random.nextInt(5) &#43; 18;

49 for (int j &#61; 0; j <4; j&#43;&#43;) {

50 name &#43;&#61; (char) (random.nextInt(26) &#43; 97);

51 }

52 Students stu2 &#61; new Students(name, credit, age);

53 myl2.add(stu2);

54 name &#61; "";

55 }

56 System.out.println("Size is of myl2 "&#43; myl2.size());

57 for(int i &#61; 0; i

58 Students stu2 &#61; (Students) myl2.get(i);

59 stu2.show();

60 }

61

62

63

64 myl.add(1, myl2);

65 System.out.println("Size is of myl1 "&#43; myl.size());

66 for(int i &#61; 0; i

67 Students stu2 &#61; (Students) myl.get(i);

68 stu2.show();

69 }

70

71

72 }

73

74 }

结果输出&#xff1a;

65aa6a93642aaa32683ab89e983842be.png



推荐阅读
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • [大整数乘法] java代码实现
    本文介绍了使用java代码实现大整数乘法的过程,同时也涉及到大整数加法和大整数减法的计算方法。通过分治算法来提高计算效率,并对算法的时间复杂度进行了研究。详细代码实现请参考文章链接。 ... [详细]
  • Java中包装类的设计原因以及操作方法
    本文主要介绍了Java中设计包装类的原因以及操作方法。在Java中,除了对象类型,还有八大基本类型,为了将基本类型转换成对象,Java引入了包装类。文章通过介绍包装类的定义和实现,解答了为什么需要包装类的问题,并提供了简单易用的操作方法。通过本文的学习,读者可以更好地理解和应用Java中的包装类。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • 本文介绍了使用Java实现大数乘法的分治算法,包括输入数据的处理、普通大数乘法的结果和Karatsuba大数乘法的结果。通过改变long类型可以适应不同范围的大数乘法计算。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 动态规划算法的基本步骤及最长递增子序列问题详解
    本文详细介绍了动态规划算法的基本步骤,包括划分阶段、选择状态、决策和状态转移方程,并以最长递增子序列问题为例进行了详细解析。动态规划算法的有效性依赖于问题本身所具有的最优子结构性质和子问题重叠性质。通过将子问题的解保存在一个表中,在以后尽可能多地利用这些子问题的解,从而提高算法的效率。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 摘要: 在测试数据中,生成中文姓名是一个常见的需求。本文介绍了使用C#编写的随机生成中文姓名的方法,并分享了相关代码。作者欢迎读者提出意见和建议。 ... [详细]
  • 多维数组的使用
    本文介绍了多维数组的概念和使用方法,以及二维数组的特点和操作方式。同时还介绍了如何获取数组的长度。 ... [详细]
  • 本文介绍了一种划分和计数油田地块的方法。根据给定的条件,通过遍历和DFS算法,将符合条件的地块标记为不符合条件的地块,并进行计数。同时,还介绍了如何判断点是否在给定范围内的方法。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Java自带的观察者模式及实现方法详解
    本文介绍了Java自带的观察者模式,包括Observer和Observable对象的定义和使用方法。通过添加观察者和设置内部标志位,当被观察者中的事件发生变化时,通知观察者对象并执行相应的操作。实现观察者模式非常简单,只需继承Observable类和实现Observer接口即可。详情请参考Java官方api文档。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
author-avatar
FEEL欧诺_625
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有