单链表的使用比较频繁、重要,记录一下学习到的相关操作
重点是辅助变量 temp 和标志位 flag 的使用
创建节点类:
//定义 HeroNode, 每个 HeroNde 对象都是一个节点 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 + "]"; } }
单链表按添加的顺序,增加节点:
//添加节点到单向链表,添加的顺序,即是链表中节点的顺序 //当不考虑编号时: // 1、找到这个链表的最后节点 // 2、将这个节点的 next 指向新的节点 public void add(HeroNode heroNode){ //头节点不能动,故用辅助变量 temp HeroNode temp = head; //遍历链表,找到最后的节点 while(true){ //找到链表的最后 if(temp.next == null) break; //没有找到,temp 后移 temp = temp.next; } //当结束 while 循环时,temp指向 链表的最后 //将这最后的节点的 next 指向 新的节点(即要添加进链表的节点:heroNode) temp.next = heroNode; }
根据排名插入节点,即插入节点会自动排序
//根据排名添加英雄,自动排序,如果已经有,则提示添加失败,并给出提示 public void addByOrder(HeroNode heroNode){ //头节点不能使用,需要通过辅助指针来帮助找到添加的位置 //temp 添加位置前一个的节点 //flag 标记想要添加的编号是否存在,默认为 false HeroNode temp = head; boolean flag = false; while(true){ //为 null 说明temp已经在链表的最后,故退出 if(temp.next == null) break; // > 说明想要的位置已经找到: // 按从小到大排列的,所以后一个节点,应该比待添加节点的序号大 // = 说明已经存在这个节点(位置在当前temp的下一个节点),所以将 flag 值改变后退出,并返回提示信息 if(temp.next.no > heroNode.no) { break; }else if(temp.next.no == heroNode.no){ flag = true; break; } //未查到合适的添加位置,后移一位,遍历当前链表 temp = temp.next; } if(flag) { System.out.printf("准备插入的英雄编号: %d 已经存在, 不能加入\n", heroNode.no); }else { //插入到链表中,temp的后面 heroNode.next = temp.next; temp.next = heroNode; } }
修改节点内容:
public void updata(HeroNode newHeroNode){ //判断链表是否为空 if(head.next == null) { System.out.println("链表为空"); return; } //定义辅助指针 temp 与 标志 flag,默认值为:false HeroNode temp = head; boolean flag = false; //遍历 while(true){ //遍历完都没有找到 if(temp.next == null) break; //找到了,把 flag 置为 true if(temp.next.no == newHeroNode.no){ flag = true; break; } //遍历 temp = temp.next; } //退出了 while 要么找到,要么没找到,由 flag 来判断 if(flag){ temp.next.name = newHeroNode.name; temp.next.nickname = newHeroNode.nickname; } else{ System.out.printf("未找到编号为: %d 的节点,不能修改", temp.no); } }
删除节点:
public void del(int no){ HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null) break; if(temp.next.no == no){ flag = true; break; } temp = temp.next; } if(flag){ temp.next = temp.next.next; } else{ System.out.printf("你想要删除的节点 %d 不存在,删除失败", no); } }
总的全部代码(包括测试):
package com.chen; /** * @author 淡 * @create 2020-02-09 13:49 */ public class linkedlist { 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(hero3); // singleLinkedList.add(hero4); // singleLinkedList.add(hero2); //英雄加入链表 singleLinkedList.addByOrder(hero1); singleLinkedList.addByOrder(hero3); singleLinkedList.addByOrder(hero4); singleLinkedList.addByOrder(hero2); singleLinkedList.addByOrder(hero3); //显示链表 singleLinkedList.list(); HeroNode newHeroNode = new HeroNode(2,"小卢","玉麒麟~~"); singleLinkedList.updata(newHeroNode); System.out.println("修改后的链表:"); singleLinkedList.list(); singleLinkedList.del(1); singleLinkedList.del(4); singleLinkedList.del(2); singleLinkedList.del(3); System.out.println("删除后的链表:"); singleLinkedList.list(); } } //定义 SingleLinkedList 管理我们的英雄 class SingleLinkedList{ //初始化一个头节点,不放任何数据 private HeroNode head = new HeroNode(0, "", ""); //添加节点到单向链表,添加的顺序,即是链表中节点的顺序 //当不考虑编号时: // 1、找到这个链表的最后节点 // 2、将这个节点的 next 指向新的节点 public void add(HeroNode heroNode){ //头节点不能动,故用辅助变量 temp HeroNode temp = head; //遍历链表,找到最后的节点 while(true){ //找到链表的最后 if(temp.next == null) break; //没有找到,temp 后移 temp = temp.next; } //当结束 while 循环时,temp指向 链表的最后 //将这最后的节点的 next 指向 新的节点(即要添加进链表的节点:heroNode) temp.next = heroNode; } //根据排名添加英雄,自动排序,如果已经有,则提示添加失败,并给出提示 public void addByOrder(HeroNode heroNode){ //头节点不能使用,需要通过辅助指针来帮助找到添加的位置 //temp 添加位置前一个的节点 //flag 标记想要添加的编号是否存在,默认为 false HeroNode temp = head; boolean flag = false; while(true){ //为 null 说明temp已经在链表的最后,故退出 if(temp.next == null) break; // > 说明想要的位置已经找到: // 按从小到大排列的,所以后一个节点,应该比待添加节点的序号大 // = 说明已经存在这个节点(位置在当前temp的下一个节点),所以将 flag 值改变后退出,并返回提示信息 if(temp.next.no > heroNode.no) { break; }else if(temp.next.no == heroNode.no){ flag = true; break; } //未查到合适的添加位置,后移一位,遍历当前链表 temp = temp.next; } if(flag) { System.out.printf("准备插入的英雄编号: %d 已经存在, 不能加入\n", heroNode.no); }else { //插入到链表中,temp的后面 heroNode.next = temp.next; temp.next = heroNode; } } public void updata(HeroNode newHeroNode){ //判断链表是否为空 if(head.next == null) { System.out.println("链表为空"); return; } //定义辅助指针 temp 与 标志 flag,默认值为:false HeroNode temp = head; boolean flag = false; //遍历 while(true){ //遍历完都没有找到 if(temp.next == null) break; //找到了,把 flag 置为 true if(temp.next.no == newHeroNode.no){ flag = true; break; } //遍历 temp = temp.next; } //退出了 while 要么找到,要么没找到,由 flag 来判断 if(flag){ temp.next.name = newHeroNode.name; temp.next.nickname = newHeroNode.nickname; } else{ System.out.printf("未找到编号为: %d 的节点,不能修改", temp.no); } } public void del(int no){ HeroNode temp = head; boolean flag = false; while(true){ if(temp.next == null) break; if(temp.next.no == no){ flag = true; break; } temp = temp.next; } if(flag){ temp.next = temp.next.next; } else{ System.out.printf("你想要删除的节点 %d 不存在,删除失败", no); } } //显示链表(遍历显示) public void list(){ //判断链表是否为空 if(head.next == null){ System.out.println("链表为空!"); return; } //头节点不能动,故定义一个辅助变量,来帮助遍历 HeroNode temp = head.next; while (true){ //判断是否到链表最后 if(temp == null) break; //未到最后,输出节点信息 System.out.println(temp); // temp 后移到下一节点 temp = temp.next; } } } //定义 HeroNode, 每个 HeroNde 对象都是一个节点 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 + "]"; } }