(1)链表是以节点的方式来存储
    (2)每个节点包含data域和next域:指向下一个节点
    (3)链表的各个节点不一定是连续存储
    (4)链表分带头节点的和没有头节点的链表,根据实际需求来定

    1. /**
    2. * 单向链表节点
    3. */
    4. public class Node {
    5. /**
    6. * 节点id
    7. */
    8. private Integer id;
    9. /**
    10. * 节点数据
    11. */
    12. private String data;
    13. /**
    14. * 指向下一个节点
    15. */
    16. private Node next;
    17. public Node(Integer id, String data) {
    18. this.id = id;
    19. this.data = data;
    20. }
    21. public Integer getId() {
    22. return id;
    23. }
    24. public void setId(Integer id) {
    25. this.id = id;
    26. }
    27. public String getData() {
    28. return data;
    29. }
    30. public void setData(String data) {
    31. this.data = data;
    32. }
    33. public Node getNext() {
    34. return next;
    35. }
    36. public void setNext(Node next) {
    37. this.next = next;
    38. }
    39. @Override
    40. public String toString() {
    41. return "Node{" + "id=" + id + ", data='" + data + '\'' + '}';
    42. }
    43. }
    1. /**
    2. * 单向链表
    3. */
    4. public class LinkedList {
    5. /**
    6. * 初始化一个头节点
    7. */
    8. private Node head = new Node(null, null);
    9. /**
    10. * 新增节点
    11. */
    12. public void add(Node node) {
    13. Node temp = head;
    14. // 遍历链表,找到最后一个节点
    15. while(true) {
    16. if (temp.getNext() == null) {
    17. break;
    18. }
    19. temp = temp.getNext();
    20. }
    21. // 当退出while循环时,temp指向了最后一个节点
    22. temp.setNext(node);
    23. }
    24. /**
    25. * 修改节点
    26. * @param node
    27. */
    28. public void update(Node node) {
    29. if (head.getNext() == null) {
    30. System.out.println("链表为空,修改失败!");
    31. }
    32. Node temp = head.getNext();
    33. // 遍历链表
    34. while(temp != null) {
    35. if (Objects.equals(temp.getId(), node.getId())) {
    36. temp.setData(node.getData());
    37. }
    38. temp = temp.getNext();
    39. }
    40. }
    41. /**
    42. * 删除节点
    43. */
    44. public void del(Integer id) {
    45. if (head.getNext() == null) {
    46. System.out.println("链表为空,删除失败!");
    47. }
    48. Node temp = head;
    49. // 遍历链表
    50. while(temp != null) {
    51. // 表示到链表最后,直接退出
    52. if (temp.getNext() == null) {
    53. break;
    54. }
    55. // 找到待删除节点的前一个节点
    56. if (Objects.equals(temp.getNext().getId(), id)) {
    57. temp.setNext(temp.getNext().getNext());
    58. }
    59. temp = temp.getNext();
    60. }
    61. }
    62. /**
    63. * 获取节点
    64. */
    65. public Node get(Integer id) {
    66. if (head.getNext() == null) {
    67. System.out.println("链表为空");
    68. return null;
    69. }
    70. Node temp = head.getNext();
    71. while(temp != null) {
    72. if (Objects.equals(temp.getId(), id)) {
    73. return temp;
    74. }
    75. temp = temp.getNext();
    76. }
    77. return null;
    78. }
    79. /**
    80. * 查看所有节点
    81. */
    82. public void list() {
    83. if (head.getNext() == null) {
    84. System.out.println("链表为空");
    85. return;
    86. }
    87. Node temp = head.getNext();
    88. while(temp != null) {
    89. System.out.println(temp);
    90. temp = temp.getNext();
    91. }
    92. }
    93. /**
    94. * 链表节点反转
    95. * @return
    96. */
    97. public void reverse() {
    98. if (head.getNext() == null) {
    99. return;
    100. }
    101. LinkedList tempList = new LinkedList();
    102. // 遍历原链表,依次放在临时链表的最前面
    103. Node temp = head.getNext();
    104. while(temp != null) {
    105. // 1、首先找到原链表当前节点的下一个节点
    106. Node nextNode = temp.getNext();
    107. // 2、把新链表的第一个节点插入到当前节点的后面
    108. temp.setNext(tempList.head.getNext());
    109. // 3、把当前节点插入新链表的第一个节点中
    110. tempList.head.setNext(temp);
    111. // 4、继续寻找下一个节点
    112. temp = nextNode;
    113. }
    114. head.setNext(tempList.head.getNext());
    115. }
    116. /**
    117. * 反向打印
    118. */
    119. public void reversePrint() {
    120. reversePrint2(head.getNext());
    121. }
    122. /**
    123. * 反向输出(递归)
    124. */
    125. private void reversePrint2(Node node) {
    126. if (node != null) {
    127. reversePrint2(node.getNext());
    128. System.out.println(node);
    129. }
    130. }
    131. public static void main(String[] args) {
    132. LinkedList linked = new LinkedList();
    133. Scanner scanner = new Scanner(System.in);
    134. boolean loop = true;
    135. while (loop) {
    136. System.out.print("【单向链表】新增(1)、查找(2)、修改(3)、删除(4)、反转(5)、反向打印(6)、打印(7)、退出(0):");
    137. Integer key = scanner.nextInt();
    138. switch (key) {
    139. case 1:
    140. System.out.print("新增Id:");
    141. int id = scanner.nextInt();
    142. System.out.print("新增Data:");
    143. String data = scanner.next();
    144. Node node = new Node(id, data);
    145. linked.add(node);
    146. break;
    147. case 2:
    148. System.out.print("查找Id:");
    149. int id2 = scanner.nextInt();
    150. System.out.println(linked.get(id2));
    151. break;
    152. case 3:
    153. System.out.print("修改Id:");
    154. int updateId = scanner.nextInt();
    155. System.out.print("修改Data:");
    156. String updateData = scanner.next();
    157. Node updateNode = new Node(updateId, updateData);
    158. linked.update(updateNode);
    159. break;
    160. case 4:
    161. System.out.print("删除Id:");
    162. int deleteId = scanner.nextInt();
    163. linked.del(deleteId);
    164. break;
    165. case 5:
    166. linked.reverse();
    167. System.out.println("反转完成!");
    168. break;
    169. case 6:
    170. linked.reversePrint();
    171. break;
    172. case 7:
    173. linked.list();
    174. break;
    175. case 0:
    176. scanner.close();
    177. loop = false;
    178. break;
    179. default: break;
    180. }
    181. }
    182. System.out.println("程序退出。。。");
    183. }
    184. }