单链表应用实例及代码实现
问题:使用带 head 头的单向链表实现 –英雄列表管理完成对英雄人物的增删改查操作。
首先准备一个hero类:
1. class hero { 2. private int num;//序号(排名) 3. private String name;//名称 4. private String nikname;//别名 5. private hero next;//指向下一个 6. 7. public hero(int num, String name, String nikname) { ... } //构造器 8. 9. public int getNum() { ... } 10. public void setNum(int num) { ... } 11. public String getName() { ... } 12. public void setName(String name) { ... } 13. public String getNikname() { ... } 14. public void setNikname(String nikname) { ... } 15. public hero getNext() { ... } 16. public void setNext(hero next) { ... } 17. 18. @Override 19. public String toString() { ... } //为了显示方便显示重写tostring 20. }
1) 第一种方法:在添加英雄时,直接添加到链表的尾部(add())
思路分析:
添加(创建)
1、先创建一个head头节点(①不存放具体数据,②作用就是表示单链表头next)
private hero head = new hero(-1, "", ""); //先初始化一个头节点,头节点不能动,不存放具体数据
2、之后我们每添加一个节点,就直接加入到链表的最后
遍历
1、通过一个辅助变量遍历,帮助遍历整个链表
2) 第二种方式在添加英雄时,根据排名将英雄插入到指定位置(如果有这个排名,则添加失败,并给出提示)
思路分析:
1、首先找到新添加的节点的位置,是通过辅助变量,通过遍历来搞定
2、 新的节点.next=temp.next (temp为插入后的新节点的前一个节点)
3、将temp.next=新的节点
3) 修改节点
思路分析:
1、 先找到该节点,通过遍历
2、 temp.name = newHero.name ; temp.nickname= newHero.nickname;
4) 删除节点(delete())
思路分析:
1、先找到需要删除的这个节点的前一个节点temp
2、 temp.next=temp.next.next
3、删除的节点,将不会有其他引用,会被GC掉
单链表代码实现:
1. public class singlelinkedlist { 2. //先初始化一个头节点,头节点不能动,不存放具体数据 3. private hero head = new hero(-1, "", ""); 4. 5. //添加节点到单向链表 6. /** 7. * 思路:当不考虑标编号顺序时 8. * 1、找到当前链表的最后节点 9. * 2、将最后这个节点的next指向新的节点 10. */ 11. public void add(hero h) { 12. //因为head节点不能动,因此我们需要一个辅助变量temp 13. hero temp = head; 14. //遍历链表,找到最后一个节点 15. while (true) { 16. if (temp.getNext() == null) { 17. break; 18. } 19. //如果没有到最后,将temp后移 20. temp = temp.getNext(); 21. } 22. //当退出while循环时,temp就指向了链表的最后 23. //将最后这个节点的next指向新的节点 24. temp.setNext(h); 25. } 26. 27. //第二种方式在添加英雄时,根据排名将英雄插入到指定位置 28. //(如果有这个排名,则添加失败,并给出提示) 29. public void addByOrder(hero h) { 30. //因为头节点不能动,因此我们仍然通过一个辅助指针(变量)来帮助找到添加的位置 31. //因为单链表,因为我们找的temp是位于 添加位置的前一个节点,否则插入不了 32. hero temp = head; 33. boolean flag = false;// flag 标志添加的编号是否存在,默认为 false 34. while (true) { 35. if (temp.getNext() == null) {//说明 temp 已经在链表的最后 36. break; 37. } else if (temp.getNext().getNum() > h.getNum()) {//位置找到,就在 temp 的后面插入 38. break; 39. } else if (temp.getNext().getNum() == h.getNum()) {//说明希望添加的 heroNode 的编号已然存在 40. flag = true; 41. break; 42. } 43. temp = temp.getNext();//后移,遍历当前链表 44. } 45. if (flag) { //不能添加,说明编号存在 46. System.out.println("添加的序号为" + h.getNum() + "的英雄序号已经存在,添加失败。"); 47. return; 48. } 49. //插入到链表中, temp 的后面 50. h.setNext(temp.getNext()); 51. temp.setNext(h); 52. } 53. 54. //显示链表(遍历) 55. public void show() { 56. //判断链表是否为空 57. if (head.getNext() == null) { 58. System.out.println("show():链表为空。。。。"); 59. return; 60. } 61. //因为头节点,不能动,因此我们需要一个辅助变量来遍历 62. hero temp = head.getNext(); 63. while (true) { 64. //判断是否到链表最后 65. if (temp == null) { 66. break; 67. } 68. //输出节点的信息 69. System.out.println(temp.toString()); 70. //将 temp 后移, 一定小心 71. temp = temp.getNext(); 72. } 73. } 74. 75. //修改节点的信息, 根据 no 编号来修改,即 no 编号不能改. 76. //说明 77. //1. 根据 newHeroNode 的 no 来修改即可 78. public void update(hero h) { 79. hero temp = head.getNext();//定义一个辅助变量 80. boolean flag = false;//表示是否找到该节点 81. //判断链表是否空 82. if (head.getNext() == null) { 83. System.out.println("update():链表为空。。。。"); 84. return; 85. } 86. //找到需要修改的节点, 根据 num值 87. while (true) { 88. if (temp == null) { 89. break;//已经遍历完链表 90. } 91. if (temp.getNum() == h.getNum()) { 92. flag = true; 93. break; 94. } 95. temp = temp.getNext(); 96. } 97. if (flag) { 98. temp.setName(h.getName()); 99. temp.setNikname(h.getNikname()); 100. } else {//没有找到 101. System.out.printf("没有找到 编号 %d 的节点,不能修改\n", h.getNum()); 102. } 103. } 104. 105. //删除节点 106. //思路 107. //1. head 不能动,因此我们需要一个 temp 辅助节点找到待删除节点的前一个节点 108. //2. 说明我们在比较时,是 temp.next.no 和需要删除的节点的 no 比较 109. public void delete(int n) { 110. hero temp = this.head; 111. boolean flag = false;// 标志是否找到待删除节点的 112. if (head.getNext() == null) { 113. System.out.println("delete():链表为空。。。。"); 114. return; 115. } 116. while (true) { 117. if (temp.getNext() == null) {//已经到链表的最后 118. break; 119. } 120. if (temp.getNext().getNum() == n) {//找到的待删除节点的前一个节点 temp 121. flag = true; 122. break; 123. } 124. temp = temp.getNext();//temp 后移,遍历 125. } 126. if (flag) { 127. temp.setNext(temp.getNext().getNext()); 128. } else { 129. System.out.printf("没有找到 编号 %d 的节点,不能删除\n", n); 130. } 131. 132. } 133. 134. }