该示例的代码是在前一篇的基础上进行修改的.
public class SingleLinkedListDemo { public static void main(String[] args) { //先创建几个节点 Node node1 = new Node(1, "老子", "太上老君"); Node node2 = new Node(2, "王达", "玉皇大帝"); Node node3 = new Node(3, "萧炎", "炎帝"); // Node node4 = new Node(3, "萧炎", "炎帝"); SingleLinkedList linkedList = new SingleLinkedList(); // 调用顺序添加的方法,请注意添加顺序1,3,2 linkedList.orderAdd(node1); linkedList.orderAdd(node3); linkedList.orderAdd(node2); // linkedList.orderAdd(node4); linkedList.list(); //打印 } } /** * 定义一个链表,用于管理每个Node节点 */ class SingleLinkedList { // 初始化一个头节点, 不能动,用于去找链表的其它节点 private Node head = new Node(0); //添加节点到单向链表尾部 public void add(Node node) { // 1. 如何找到链表的尾节点 Node temp = head; //遍历链表,找到最后的节点 while (true) { if (temp.next == null) { break; } temp = temp.next; } // 当退出while循环时, temp指向了链表的最后 temp.next = node; } /** * 按照no编号进行添加 . 如no=3,那么它应该加在no=2节点之后,如果有no=3的节点,报错提示 * * @param node */ public void orderAdd(Node node) { // 因为head节点不能动,所以需要使用一个辅助节点 // 而且这个temp节点一定是添加节点的前一个节点 Node temp = head; // 标识添加的编号是否存在 boolean flag = false; //遍历链表,找到最后的节点 while (true) { if (temp.next == null) { // 说明temp是尾节点 break; } /* 注意: 这儿为啥不使用temp.no < node.no是判断吗? 假设temp.no =1, 现在添加2, 1<2,所以将2节点放到1点后面, 再添加3, 因为是从head节点开始遍历,所以1<3 , 所以将3节点添加到1点后面, 正确的是遍历到2号节点, 2<3, 添加到2号节点后面.但谁让从head节点开始遍历,1比2先出现呢... */ if (temp.next.no > node.no) {// 找到正确的节点编号了 break; } else if (temp.next.no == node.no) { // 说明编号存在 flag = true; break; } temp = temp.next; } if (flag) { // 不能添加 ,编号已经存在 System.out.printf("%d已经存在 ,不能添加!\n", node.no); } else { // 插入到链表中 node.next = temp.next; // 表示插入到temp.next节点之前 temp.next = node; // 表示插入到temp的节点之后 } } public void list() { if (head.next == null) { System.out.println("链表为空"); return; } Node temp = head.next; while (true) { // 判断是否到链表最后 if (temp == null) { break; } // 打印 System.out.println(temp); temp = temp.next; } } } class Node { int no; String name; String nickName; /** * 指向下一个节点 */ public Node next; public Node(int no) { this.no = no; } public Node(int no, String name, String nickName) { this.no = no; this.name = name; this.nickName = nickName; } @Override public String toString() { return "Node{" + "no=" + no + ", name='" + name + '\'' + ", nickName='" + nickName + '}'; } }
打印结果
Node{no=1, name='老子', nickName='太上老君} Node{no=2, name='王达', nickName='玉皇大帝} Node{no=3, name='萧炎', nickName='炎帝}
搞定收工!
补充
删除操作
/** * 删除一个节点 * @param node */ public void delete(Node node) { Node tempNode = head; boolean flag = false; while (true) { if (tempNode.next == null) { System.out.println("没有找到删除的节点"); return; } if (tempNode.next.no == node.no) { flag = true; break; } tempNode = tempNode.next; } if (flag) { tempNode.next = tempNode.next.next; } else { System.out.printf("没找到删除的节点:{}", node.no); } }
反转操作
/** * 将链表进行倒序 * <p> * 例如原链表编号是: 1,2,3 ----> 3,2,1 * <p> * 这个代码还是很有意思的, 都是看hashMap源码的功劳 */ public void reverse() { Node tail = null, cur, next; cur = head.next; while (cur != null) { next = cur.next; // 下面两行代码就是将当前节点添加到新链表的头部 cur.next = tail; tail = cur; cur = next; } // 这行代码就是将倒序后的链表挂在head节点之后. head.next = tail; }
更新操作
/** * 根据节点的编号去修改节点信息 * 即: 节点编号不会发生改变 * @param node */ public void update(Node node) { if (head.next == null) { System.out.println("链表为空"); return; } // 找到需要修改的节点 // 定义一个辅助节点 Node temp = head.next; boolean flag = false; // 表示是否找到该节点 while (true) { if (temp == null) { break; // 链表已经遍历结束 , 没有找到 } if (temp.no == node.no) { System.out.println( "找到修改节点"); flag = true; break; } temp = temp.next; } if (flag) { temp.name = node.name; temp.nickName = node.nickName; } else { // 没找到 System.out.printf("没有找编号为{}的节点",node.no); } }
日拱一卒无有尽,功不唐捐终入海