• Java单链表


    链表的介绍:

    1) 链表是以节点的方式来储存的,是链式存储结构

    2)每个节点包含data域和next域,next域指向下一个节点

    3)链表内存储的元素不一定连续

    4)链表分带头节点的链表和不带头节点的链表
    ​​​​
    ​​​​

    注:此处head为头节点并不存储数据,仅仅用来标识链表的头

    单链表应用实例:

    增:

    思路分析1:

    (1)先创建一个head节点

    (2)后面没添加一个节点,就直接加入链表的最后

    遍历:

    (1)通过一个辅助变量遍历,帮助遍历整个链表

    思路分析2:

    改:

    思路:

    (1)先找到该节点,通过遍历

    (2)temp.name== newHeroNode.name

            temp.nickname == newHeroNode.name

     

    删:

    思路分析:

    即需要将指针指向新的节点即可

    完整代码:

    1. /**
    2. * 应用实例:
    3. * 使用带head头的单项链表实现-水浒英雄排行榜管理:
    4. * 1、完成对英雄任务的增删改查
    5. * 2、第一种方法在添加英雄时,直接添加到链表的尾部
    6. * 3、第二种方法在添加英雄时,根据排名将英雄插入到指定位置
    7. */
    8. public class LinkedDEmo1{
    9. public static void main(String[] args) {
    10. //进行测试
    11. //先创建节点
    12. HeroNode hero1 = new HeroNode(1,"宋江","及时雨");
    13. HeroNode hero2 = new HeroNode(2,"卢俊义","玉麒麟");
    14. HeroNode hero3 = new HeroNode(3,"吴用","智多星");
    15. HeroNode hero4 = new HeroNode(4,"林冲","豹子头");
    16. //创建要给的链表
    17. SingleLinkedList singleLinkedList = new SingleLinkedList();
    18. // //加入
    19. // singleLinkedList.add(hero1);
    20. // singleLinkedList.add(hero2);
    21. // singleLinkedList.add(hero3);
    22. // singleLinkedList.add(hero4);
    23. //加入按照编号顺序
    24. singleLinkedList.addByOrder(hero1);
    25. singleLinkedList.addByOrder(hero4);
    26. singleLinkedList.addByOrder(hero3);
    27. singleLinkedList.addByOrder(hero2);
    28. // singleLinkedList.addByOrder(hero1);
    29. //显示一把
    30. singleLinkedList.list();
    31. //test the code to modify the node
    32. HeroNode newHeroNode = new HeroNode(2,"小路","玉麒麟??");
    33. singleLinkedList.update(newHeroNode);
    34. System.out.println("\n the situation after changing");
    35. singleLinkedList.list();
    36. // test to delete a node
    37. singleLinkedList.del(1);
    38. singleLinkedList.del(2);
    39. singleLinkedList.del(3);
    40. singleLinkedList.del(1);
    41. singleLinkedList.del(4);
    42. System.out.println("the situation after delete");
    43. singleLinkedList.list();
    44. }
    45. }
    46. //定义一个SingleLinkedlist管理英雄
    47. class SingleLinkedList{
    48. //先初始化一个头节点,头节点不要动
    49. private HeroNode head= new HeroNode(0,"","");//头节点不存放具体数据仅仅表示此为链表头
    50. //添加节点到单向链表
    51. //当不考虑编号的顺序时候,找到当前链表的最后节点,将最后这个节点的next域指向新的节点
    52. public void add(HeroNode heroNode){
    53. //因为head节点不能动,因此我们需要一个辅助便利temp
    54. HeroNode temp =head;
    55. //遍历链表,找到最后
    56. while(true){
    57. //找到链表的最后
    58. if (temp.next == null){
    59. break;
    60. }
    61. //如果没找到最后,temp后移
    62. temp = temp.next;
    63. }
    64. //当退出while循环,temp指向链表最后
    65. //将最后这个节点的next指向新的节点
    66. temp.next = heroNode;
    67. }
    68. //第二种方式在添加英雄时候,根据排名将英雄插入到指定的位置
    69. //(如果有这个排名,则添加失败,并给出提示)
    70. public void addByOrder(HeroNode heroNode){
    71. //头指针不能动,通过辅助指针来遍历
    72. //因为单链表,因为我们找的temp是位于添加位置的前一个节点,否则插入不了
    73. HeroNode temp = head;
    74. boolean flag = false; //标识添加的编号是否存在,默认为false
    75. while (true) {
    76. if (temp.next == null) {//说明temp已经在链表最后
    77. break;
    78. }
    79. if (temp.next.no > heroNode.no) {
    80. //位置找到了,就在temp的后面
    81. break;
    82. } else if (temp.next.no == heroNode.no) {
    83. //说明希望添加的heronode的编号已经存在
    84. flag = true; //说明编号存在
    85. break;
    86. }
    87. temp = temp.next;//后移,遍历当前链表
    88. }
    89. //判断flag 的值
    90. if (flag) {//不能添加,说明编号存在
    91. System.out.printf("准备插入的英雄编号%d已经存在了,不能加入\n",heroNode.no);
    92. }else{
    93. //插入到链表中,temp后面
    94. heroNode.next = temp.next;
    95. temp.next = heroNode;
    96. }
    97. }
    98. //修改节点的信息,根据编号来修改,即no编号不能改
    99. //1、根据newHeroNode的no来修改即可
    100. public void update(HeroNode newHeroNode){
    101. //判断是否为空
    102. if (head.next == null){
    103. System.out.println("link is empty");
    104. return;
    105. }
    106. //find the node need to modify, according to the number
    107. //Define an auxiliary variable
    108. HeroNode temp = head.next;
    109. boolean flag = false;
    110. while(true){
    111. if (temp.next==null){
    112. break;// reach the end of the link
    113. }
    114. if(temp.no == newHeroNode.no){
    115. //find it
    116. flag = true;
    117. break;
    118. }
    119. temp = temp.next;
    120. }
    121. //according to the flag to determine whether to find nodes that need to be modified
    122. if(flag == true){
    123. temp.name = newHeroNode.name;
    124. temp.nickname = newHeroNode.nickname;
    125. }else{
    126. //did not find it
    127. System.out.printf("Node with number %d not found",newHeroNode.no);
    128. }
    129. }
    130. //显示链表遍历
    131. public void list(){
    132. //判断链表是否为空
    133. if(head.next == null){
    134. System.out.println("链表为空");
    135. return;
    136. }
    137. //因为头节点不能动,因此通过一个辅助变量遍历
    138. HeroNode temp = head.next;
    139. while(true){
    140. //判断是否到链表最后
    141. if(temp == null){
    142. break;
    143. }
    144. //输出节点信息
    145. System.out.println(temp);
    146. //将temp后移
    147. temp = temp.next;
    148. }
    149. }
    150. /**
    151. * delete the node
    152. * 1、we should try to find the node before the node to be deleted:temp
    153. * 2、temp.next = temp.next.next(The pointer needs to be redirected to the next node of the node to be deleted )
    154. *3、The deleted node will not have any other references and will be recycled by the garbage collection mechanism
    155. */
    156. // 1、The head node cannot be moved, so we need a temp auxiliary node to locate the previous node of the node to be deleted
    157. // 2、s说明,我们在比较时,是temp。next。no 和需要删除的节点的no进行比较
    158. public void del(int no){
    159. HeroNode temp=head;
    160. boolean flag = false;
    161. while(true){
    162. if (temp.next==null){
    163. break;// reach the end of the link
    164. }
    165. if(temp.next.no == no){
    166. //找到了待删除节点的前一个节点temp
    167. flag =true;
    168. break;
    169. }
    170. temp = temp.next;//temp后移,遍历
    171. }
    172. //判断flag
    173. if(flag){
    174. //可以删除
    175. temp.next =temp.next.next;
    176. }else{
    177. System.out.printf("要删除的%d节点不存在\n" ,no);
    178. }
    179. }
    180. }
    181. //定义一个HeroNode,每个HeroNode对象就是一个节点
    182. class HeroNode{
    183. public int no;
    184. public String name;
    185. public String nickname;
    186. public HeroNode next; //指向下一个节点
    187. //构造器
    188. public HeroNode(int no, String name, String nickname){
    189. this.no = no;
    190. this.name =name;
    191. this.nickname =nickname;
    192. }
    193. //为了显示方法,我们重写toString(toString方法是Java中的一个方法,它用于将一个对象转换成字符串表示形式。这个方法通常被用于调试或者打印对象的时候,
    194. // 它可以返回对象的内容或者状态信息。默认情况下,toString方法返回的是对象的类名和内存地址,但是我们可以根据需要重写这个方法来返回自定义的字符串。)
    195. /**
    196. * toString重写和不重写的区别
    197. * 1、当不重写toString方法时,当直接输入一个对象时,是调用Object.toString方法,默认的返回结果是:全类名+@+哈希值的十六进制
    198. * 2、当重写toString方法时,打印对象或者拼接对象时,都会调用该对象声名好的toString形式,返回返回结果和声明结果保持一致
    199. */
    200. @Override
    201. public String toString() {
    202. return "HeroNode{" +
    203. "no=" + no +
    204. ", name='" + name + '\'' +
    205. ", nickname='" + nickname + '\'' +
    206. "}";
    207. }
    208. }

  • 相关阅读:
    [附源码]计算机毕业设计基于Springboot景区直通车服务系统
    笔试强训Day14&&Day15
    已解决org.springframework.web.client.HttpServerErrorException: 500服务器端HTTP调用错误的正确解决方法,亲测有效!!!
    Terraform基础设施自动化部署教程
    内聚力模型
    Spring 中 Bean 的作用域和生命周期
    小红书达人怎么对接,博主沟通流程汇总!
    JDK17 New Feature
    引入gitlab仓库代码到npm包的教程
    2023_Spark_实验十二:Spark高级算子使用
  • 原文地址:https://blog.csdn.net/qq_37801888/article/details/133468267