前言
用Java实现单链表的增删查改
参考视频
1、程序代码
详情介绍的话,可以看看原视频说的思路和代码分步写法。
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+"]";
}
}
2. 结果展示
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=智多星]
3. 总结
- 先建立节点类,比如说英雄类(节点)
- 再建立单链表类
- 测试类,进行增删改查操作
逻辑思路 容易理解,但实际代码量还是比较大的,理解起来也有点难度,建议多手打几遍,多用几下,慢慢理解就好。