用Java实现单链表的增删查改
参考视频
详情介绍的话,可以看看原视频说的思路和代码分步写法。
package Java.nian_linked_list; public class SingleLinkedListDemo { public static void main(String[] args) { // 测试 // 先创建节点 HeroNode hero1 = new HeroNode(1, "宋江", "及时雨"); HeroNode hero2 = new HeroNode(2, "卢俊义", "玉麒麟"); HeroNode hero3 = new HeroNode(3, "吴用", "智多星"); HeroNode hero4 = new HeroNode(4, "林冲", "豹子头"); // 创建要给的链表 SingleLinkedList singleLinkedList = new SingleLinkedList(); // 添加节点 // singleLinkedList.add(hero1); // singleLinkedList.add(hero2); // singleLinkedList.add(hero3); // singleLinkedList.add(hero4); // 加入按照编号的顺序 singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero3); singleLinkedList.addByOrder(hero2); // 显示一下 singleLinkedList.list(); // 测试修改节点的代码 HeroNode newHeroNode = new HeroNode(2, "小卢", "玉麒麟~~~"); singleLinkedList.update(newHeroNode); System.out.println("修改后的链表情况~~~"); // 显示一下 singleLinkedList.list(); // 删除一个节点 singleLinkedList.del(1); singleLinkedList.del(4); System.out.println("删除后的链表情况~~~"); // 显示一下 singleLinkedList.list(); } } // 定义SingleLinkedList 管理我们的英雄 class SingleLinkedList{ // 先初始化一个头节点,头节点不要动,不存放任何具体的数据 private HeroNode head = new HeroNode(0, "", ""); // 添加节点到单向链表 // 思路: 当不考虑编号顺序时 /** * 1. 找到当前链表的最后节点 * 2.将最后这个节点的next 指向新节点 */ public void add(HeroNode heroNode){ // 因为head 节点不能动,所以需要添加一个辅助变量 HeroNode tmp = head; // 遍历链表,找到最后 while(true){ // 找到链表最后 if(tmp.next==null){ break; } // 如果没有找到最后,将tmp 后移 tmp = tmp.next; } //当退出while 循环时,tmp 就指向了链表的最后 // 将最后这个节点的next 指向新的节点 tmp.next = heroNode; } /**第二种方式在添加英雄时,根据排名将英雄插入到指定位置 * 如果有这个排名,则添加失败,并给出提示 */ public void addByOrder(HeroNode heroNode){ // 因为头节点不能动,需要通过一个辅助指针(变量)来帮助找到添加的位置 // 单链表,找的tmp 是位于添加位置的前一个结点,否则插入不了 HeroNode temp = head; boolean flag= false; // flag 标志添加位置的编号是否存在,默认为false while(true){ if(temp.next ==null ){ // 说明temp 已经在链表最后 break; } if(temp.next.no > heroNode.no){ // 位置找到 break; } else if(temp.next.no == heroNode.no) { // 说明希望添加的heroNode编号已经存在 flag = true; break; } temp = temp.next; } // 判断flag 的值 if(flag){ // 不能添加,说明编号存在 System.out.printf("准备插入的英雄的编号%d 已经存在了,不能加入\n",heroNode.no); } else{ // 插入到链表中,temp 后面 heroNode.next= temp.next; temp.next = heroNode; } } // 修改节点信息,根据no编号来修改,即no 编号不能改 /** * 说明 * 1.根据newHeroNode 的 no 来修改即可 */ public void update(HeroNode newHeroNode){ // 判断是否为空 if (head.next == null){ System.out.println("链表为空~"); return ; } // 找到需要修改的节点,根据no 编号 // 定义一个辅助变量 HeroNode temp = head.next; boolean flag = false ; // 表示是否找到该节点 while(true){ if (temp == null ){ break; // 已经遍历完链表 } if(temp.no == newHeroNode.no){ // 找到 flag = true; break; } temp = temp.next; } // 根据flag 判断是否找到要修改的节点 if(flag){ temp.name = newHeroNode.name; temp.nickname = newHeroNode.nickname; } else { // 没有找到 System.out.printf("没有找到 编号%d 的节点,不能修改\n",newHeroNode.no); } } // 删除节点 /** * 思路: * 1、head不能动,需要一个辅助节点temp 找到待删除节点前一个节点 * 2、说明我们在比较时,是temp.next.no 和需要删除的节点的no 比较 */ public void del(int no){ HeroNode temp = head; boolean flag = false; // 标志是否找到待删除的节点 while(true){ if(temp.next ==null ){ // 说明temp 已经在链表最后 break; } if(temp.next.no == no) { // 找到的待删除节点的前一个节点temp flag = true; break; } temp = temp.next; } if(flag){ // 找到,可以删除 temp.next= temp.next.next; }else{ System.out.printf("要删除的%d 节点不存在\n", no); } } // 显示链表。遍历 public void list(){ // 判断链表是否为空 if(head.next == null ){ System.out.println("链表为空"); return ; } // 因为头节点不能动,需要辅助变量 HeroNode tmp = head.next; while(true){ // 判断是否到链表最后 if(tmp == null ){ break; } // 输出节点信息 System.out.println(tmp); // 将tmp 后移,小心,, tmp = tmp.next; } } } // 定义HeroNode,每个HeroNode 对象就是一个节点 class HeroNode{ public int no; public String name; public String nickname; public HeroNode next; // 指向下一个节点 // 构造器 public HeroNode(int no,String name, String nickname){ this.no = no; this.name = name; this.nickname = nickname; } // 为了显示方便,我们重新toString @Override public String toString(){ return "HeroNode [ no=" + no + ", name="+ name +",nickname="+nickname+"]"; } }
HeroNode [ no=1, name=宋江,nickname=及时雨] HeroNode [ no=2, name=卢俊义,nickname=玉麒麟] HeroNode [ no=3, name=吴用,nickname=智多星] HeroNode [ no=4, name=林冲,nickname=豹子头] 修改后的链表情况~~~ HeroNode [ no=1, name=宋江,nickname=及时雨] HeroNode [ no=2, name=小卢,nickname=玉麒麟~~~] HeroNode [ no=3, name=吴用,nickname=智多星] HeroNode [ no=4, name=林冲,nickname=豹子头] 删除后的链表情况~~~ HeroNode [ no=2, name=小卢,nickname=玉麒麟~~~] HeroNode [ no=3, name=吴用,nickname=智多星]
逻辑思路 容易理解,但实际代码量还是比较大的,理解起来也有点难度,建议多手打几遍,多用几下,慢慢理解就好。