当前位置:   article > 正文

【数据结构】单链表的增删改查

【数据结构】单链表的增删改查
介绍

链表是有序的列表,但是它在内存中是如下存储的:

①链表以节点的方式进行存储,是链式存储

②每个节点包含 data 域、next 域:指向下一节点

③链表的各个节点不一定是连续存放的

④链表分为有头节点的链表和没有头节点的链表 

head节点

1.不存放具体数据

2.作用就是表示单链表

一、将英雄直接添加到链表尾部
  1. public class SingleLinkedListDemo {
  2. public static void main(String[] args) {
  3. //进行一个测试
  4. //先创建节点
  5. HeroNode heroNode1 = new HeroNode(1, "孙悟空", "大圣");
  6. HeroNode heroNode2 = new HeroNode(2, "猪八戒", "老猪");
  7. HeroNode heroNode3 = new HeroNode(3, "沙悟净", "沙和尚");
  8. HeroNode heroNode4 = new HeroNode(4, "唐三藏", "唐僧");
  9. //创建一个链表
  10. SingleLinkedList singleLinkedList = new SingleLinkedList();
  11. //加入
  12. singleLinkedList.add(heroNode1);
  13. singleLinkedList.add(heroNode2);
  14. singleLinkedList.add(heroNode3);
  15. singleLinkedList.add(heroNode4);
  16. //显示一把
  17. singleLinkedList.list();
  18. }
  19. }
  20. //定义StringLinkedList 管理我们的英雄
  21. class SingleLinkedList {
  22. //先初始化一个头节点,头节点不要动,不存放具体的数据
  23. private HeroNode head = new HeroNode(0, "", "");
  24. //添加节点到单向链表
  25. /*
  26. 思路:当不考虑编号顺序时
  27. 1.找到当前链表的最后节点
  28. 2.将最后这个节点的next 指向 新的节点
  29. */
  30. public void add(HeroNode heroNode) {
  31. //因为head节点不能动,因此我们需要一个辅助变量 temp
  32. HeroNode temp = head;
  33. //遍历链表,找到最后
  34. while (true) {
  35. //找到链表的最后
  36. if (temp.next == null) {
  37. break;
  38. }
  39. //如果没有找到链表的最后
  40. temp = temp.next;
  41. }
  42. //当退出while循环时,temp就指向了链表的最后
  43. temp.next = heroNode;
  44. }
  45. //显示链表【遍历】
  46. public void list() {
  47. //判断链表是否为空
  48. if (head.next == null) {
  49. System.out.println("链表为空");
  50. return;
  51. }
  52. //因为头节点不能动,因此我们需要一个辅助节点来遍历
  53. HeroNode temp = head.next;
  54. while (true) {
  55. //输出节点信息
  56. System.out.println(temp);
  57. //判断是否到链表最后
  58. if (temp.next == null) {
  59. break;
  60. }
  61. //将temp后移,一定小心,否则是死循环
  62. temp = temp.next;
  63. }
  64. }
  65. }
  66. //定义一个HeroNode,每个HeroNode 对象就是一个节点
  67. class HeroNode {
  68. public int no;
  69. public String name;
  70. public String nickname;
  71. public HeroNode next; //指向下一节点
  72. //构造器
  73. public HeroNode(int no, String name, String nickname) {
  74. this.no = no;
  75. this.name = name;
  76. this.nickname = nickname;
  77. }
  78. //为了显示方便,我们重写toString方法
  79. @Override
  80. public String toString() {
  81. return "HeroNode{" +
  82. "no=" + no +
  83. ", name='" + name + '\'' +
  84. ", nickname='" + nickname + '\'' +
  85. '}';
  86. }
  87. }
二、将英雄按照排名插入到链表中

1.首先找到新添加的节点的位置,通过辅助指针完成

2.新节点.next = temp.next

3.temp.next = 新节点

  1. public class SingleLinkedListDemo {
  2. public static void main(String[] args) {
  3. //进行一个测试
  4. //先创建节点
  5. HeroNode heroNode1 = new HeroNode(1, "孙悟空", "大圣");
  6. HeroNode heroNode2 = new HeroNode(2, "猪八戒", "老猪");
  7. HeroNode heroNode3 = new HeroNode(3, "沙悟净", "沙和尚");
  8. HeroNode heroNode4 = new HeroNode(4, "唐三藏", "唐僧");
  9. //创建一个链表
  10. SingleLinkedList singleLinkedList = new SingleLinkedList();
  11. //加入
  12. // singleLinkedList.add(heroNode1);
  13. // singleLinkedList.add(heroNode2);
  14. // singleLinkedList.add(heroNode3);
  15. // singleLinkedList.add(heroNode4);
  16. //按照编号的顺序加入
  17. singleLinkedList.addByOrder(heroNode4);
  18. singleLinkedList.addByOrder(heroNode1);
  19. singleLinkedList.addByOrder(heroNode3);
  20. singleLinkedList.addByOrder(heroNode2);
  21. //显示一把
  22. singleLinkedList.list();
  23. }
  24. }
  25. //定义StringLinkedList 管理我们的英雄
  26. class SingleLinkedList {
  27. //先初始化一个头节点,头节点不要动,不存放具体的数据
  28. private HeroNode head = new HeroNode(0, "", "");
  29. //添加节点到单向链表
  30. /*
  31. 思路:当不考虑编号顺序时
  32. 1.找到当前链表的最后节点
  33. 2.将最后这个节点的next 指向 新的节点
  34. */
  35. public void add(HeroNode heroNode) {
  36. //因为head节点不能动,因此我们需要一个辅助变量 temp
  37. HeroNode temp = head;
  38. //遍历链表,找到最后
  39. while (true) {
  40. //找到链表的最后
  41. if (temp.next == null) {
  42. break;
  43. }
  44. //如果没有找到链表的最后
  45. temp = temp.next;
  46. }
  47. //当退出while循环时,temp就指向了链表的最后
  48. temp.next = heroNode;
  49. }
  50. //第二种添加英雄的方式
  51. /*
  52. 根据排名将英雄插入到指定位置
  53. 如果有这个排名,则添加失败,并给出提示
  54. */
  55. public void addByOrder(HeroNode heroNode) {
  56. //因为头节点不能动,因此我们仍然通过一个辅助指针来帮助找到添加的位置
  57. //因为单链表,因此我们找的 temp 是位于添加位置的前一个节点,否则无法插入
  58. HeroNode temp = head;
  59. boolean flag = false; //flag标识添加的编号是否存在,默认为 false
  60. while (true) {
  61. if (temp.next == null) { //说明 temp 已经在链表的最后
  62. break;
  63. }
  64. if (temp.next.no > heroNode.no) {
  65. break;
  66. } else if (temp.next.no == heroNode.no) {
  67. flag = true; //说明编号存在
  68. break;
  69. }
  70. temp = temp.next; //后移,遍历当前链表
  71. }
  72. //判断 flag 的值
  73. if (flag) { //不能添加,说明编号存在
  74. System.out.printf("准备插入的英雄编号%d已经存在,不能加入\n", heroNode.no);
  75. } else { //插入到链表中,temp的后面
  76. heroNode.next = temp.next;
  77. temp.next = heroNode;
  78. }
  79. }
  80. //显示链表【遍历】
  81. public void list() {
  82. //判断链表是否为空
  83. if (head.next == null) {
  84. System.out.println("链表为空");
  85. return;
  86. }
  87. //因为头节点不能动,因此我们需要一个辅助节点来遍历
  88. HeroNode temp = head.next;
  89. while (true) {
  90. //输出节点信息
  91. System.out.println(temp);
  92. //判断是否到链表最后
  93. if (temp.next == null) {
  94. break;
  95. }
  96. //将temp后移,一定小心,否则是死循环
  97. temp = temp.next;
  98. }
  99. }
  100. }
  101. //定义一个HeroNode,每个HeroNode 对象就是一个节点
  102. class HeroNode {
  103. public int no;
  104. public String name;
  105. public String nickname;
  106. public HeroNode next; //指向下一节点
  107. //构造器
  108. public HeroNode(int no, String name, String nickname) {
  109. this.no = no;
  110. this.name = name;
  111. this.nickname = nickname;
  112. }
  113. //为了显示方便,我们重写toString方法
  114. @Override
  115. public String toString() {
  116. return "HeroNode{" +
  117. "no=" + no +
  118. ", name='" + name + '\'' +
  119. ", nickname='" + nickname + '\'' +
  120. '}';
  121. }
  122. }
 三、修改节点的信息
  1. //修改节点的信息,根据编号修改,即编号不能改
  2. public void update(HeroNode newHeroNode) {
  3. //判断是否空
  4. if (head.next == null) {
  5. System.out.println("链表为空");
  6. return;
  7. }
  8. //根据编号,找到需要修改的节点
  9. //定义一个辅助变量
  10. HeroNode temp = head.next;
  11. boolean flag = false; //表示是否找到该节点
  12. while (true) {
  13. if (temp == null) {
  14. break; //已经遍历完链表
  15. }
  16. if (temp.no == newHeroNode.no) {
  17. //找到
  18. flag = true;
  19. break;
  20. }
  21. temp = temp.next;
  22. }
  23. //根据flag 判断是否找到要修改的节点
  24. if (flag) {
  25. temp.name = newHeroNode.name;
  26. temp.nickname = newHeroNode.nickname;
  27. } else { //没有找到
  28. System.out.printf("没有找到编号为%d的节点,不能修改\n", newHeroNode.no);
  29. }
  30. }
四、删除节点

从单链表中删除一个节点的思路

1.我们先找到需要删除的节点的前一个节点 temp

2.temp.next = temp.next,next

3.被删除的节点将不会有其他的引用指向,会被垃圾回收机制回收

  1. //删除节点
  2. /*
  3. 思路
  4. 1.head不能动,因此我们需要一个 temp 辅助节点找到待删除节点的前一个节点
  5. 2.说明:我们在比较时,是 temp.next.no 和 需要删除节点.no 比较
  6. */
  7. public void del(int no) {
  8. HeroNode temp = head;
  9. boolean flag = false; //标识是否找到
  10. while (true) {
  11. if (temp.next == null) {
  12. break;
  13. }
  14. if (temp.next.no == no) {
  15. //找到了待删除节点的前一个节点
  16. flag = true;
  17. break;
  18. }
  19. temp = temp.next;
  20. }
  21. //判断flag
  22. if (flag == true) { //找到了
  23. temp.next = temp.next.next;
  24. } else { //没找到
  25. System.out.printf("编号为%d的节点不存在", no);
  26. }
  27. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/889299
推荐阅读
相关标签
  

闽ICP备14008679号