第一次写,不废话,直接上源代码,注释自己写的:
package Array; public class SingleChainTable { public static void main(String[] args) { HeroNode hero1 = new HeroNode(1, "宋江", "及时雨"); HeroNode hero2 = new HeroNode(6, "武松", "行者"); HeroNode hero3 = new HeroNode(5, "孙三娘", "母夜叉"); HeroNode hero4 = new HeroNode(2, "李逵", "黑旋风"); HeroNode hero5 = new HeroNode(2, "李易燃", "大脾气"); SingleLinkedList singleLinkedList = new SingleLinkedList(); // singleLinkedList.add(hero1);测试,可自己试试看 // singleLinkedList.add(hero2); // singleLinkedList.add(hero3); // singleLinkedList.add(hero4); singleLinkedList.addPosition(hero1); singleLinkedList.addPosition(hero2); singleLinkedList.addPosition(hero3); singleLinkedList.addPosition(hero4); singleLinkedList.list(); singleLinkedList.update(hero5); System.out.println("修改后的单链表为"); singleLinkedList.list(); singleLinkedList.deletePosition(hero2); System.out.println("删除编号为" + hero2.num + "的单链表为"); singleLinkedList.list(); singleLinkedList.delete(); System.out.println("删除尾结点后的单链表为"); singleLinkedList.list(); } } class SingleLinkedList { //初始化头结点,不存放数据 private HeroNode head = new HeroNode(0, "", ""); /* 尾查法,只要找到单链表尾部即可 */ public void add(HeroNode hnode) { HeroNode temp = head; while (true) { //因为尾部节点肯定指向空节点,所以就可以找到 if (temp.next == null) { break; } //此时temp指向最后; temp = temp.next;//让temp节点变成自己指向的节点 } temp.next = hnode;//等找到最后的节点,我们就让其指向新节点 } /* 该函数是将节点插入到指定位置 其原理是引入辅助变量,其 */ public void addPosition(HeroNode hnode) { HeroNode temp = head; boolean flag = false;//标记是否插入成功 while (true) { if (temp.next == null) { /*该语句可以在链表为空的时候用, 因为flag在未变为true时,也会执行下面的语句 */ break; } if (temp.next.num > hnode.num) { /*找到比该插入节点编号大的节点结束循环 在遍历单链表时,我们不能用当前节点来寻找插入 在我看来,确实最好的方法就是像视频里说的那样做 */ break; } else if (temp.next.num == hnode.num) { flag = true; break; } temp = temp.next; } if (flag) { System.out.println("添加失败"); } else { /* 下列代码要用内存图来考虑, 因为引用类型的数据在内存中是会直接改变的 所以从下列的代码来看,我让新加进来的节点也指向 我所设的temp节点的指向 然后我又将该temp节点指向我所添加的节点,这样就实现了添加的操作 */ hnode.next = temp.next; temp.next = hnode; } } //修改指定节点 public void update(HeroNode newhnode) { HeroNode temp = head; boolean flag = false; while (true) { if (temp.next == null) { break; } if (temp.num == newhnode.num) { flag = true; break; } temp = temp.next; } if (flag) { temp.name = newhnode.name; temp.nickname = newhnode.nickname; } else { System.out.println("未找到该编号未" + newhnode.num + "的节点"); } } //删除指定位置的节点 public void deletePosition(HeroNode hnode) { HeroNode temp = head; boolean flag = false; while (true) { if (temp.next == null) { break; } if (temp.next.num == hnode.num) { flag = true; break; } temp = temp.next; } if (flag) { /* 找到指定节点后我将该节点的前一个节点指向该 找到节点的后面的节点 同时我又将找到的该节点直接指向null 就完成了删除该节点的操作 还是那句话,我们在操作节点时 必须操作所需要操作的前一个节点 */ temp.next = hnode.next; hnode.next = null; } else { System.out.println("该单链表中不存在编号为" + hnode.num + "的节点"); } } //删除尾结点 public void delete() { HeroNode temp = head; while (true) { //找到尾结点的前一个结点 if (temp.next.next == null) { break; } temp = temp.next; } /*将该结点抹除, 意思就是将需要操作的前一个节点直接指向null 此时该节点的前一个节点就不会指向所删除的节点了 不要陷进某一个程序的思维中,要活跃 */ temp.next = null; } public void list() { if (head.next == null) { System.out.println("该单链表为空"); } HeroNode temp = head.next; while (true) { if (temp == null) { break; } //因为已经重写了toString方法,所以可以直接打印信息; System.out.println(temp); temp = temp.next; } } } class HeroNode { /* head节点不存储数据 作用只是表示这个单链表的头 */ int num; String name; String nickname; HeroNode next; HeroNode(int num, String name, String nickname) { this.num = num; this.name = name; this.nickname = nickname; } /* 该toString方法是为了便于方便显示该功能 在重写了toString方法后,直接可以打印需要输出的节点 */ @Override public String toString() { return "HeroNode{" + "num=" + num + ", name='" + name + '\'' + ", nickname='" + nickname + '}'; } } 运行结果: