【小白学算法】6.单链表的修改、删除

简介: 【小白学算法】6.单链表的修改、删除

接着上一章继续来看单链表。


之前对单链表进行了遍历、插入的操作,本章继续用代码来实现修改以及删除。


一、单链表的修改


修改结点信息首先需要先找到对应的结点,接着上一章的代码,也就是英雄的排名no是不能修改的,要用来找结点。


其他的信息就可以动了。


另外,还要考虑到单链表中找不到对应要修改的结点的情况。这里代码就不全贴出来了,现在继续在SingleLinkedList

中增加修改结点信息的方法:


// 修改结点信息
    // 根据结点的no来修改即可
    public void  update(HeroNode newHeroNode) {
        // 判断链表是否为空
        if (headNode.next == null) {
            System.out.println("链表为空");
            return;
        }
        // 借助辅助变量temp
        HeroNode temp = headNode.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);
        }
    }


在main方法中修改测试代码,看看结果是否符合预期。


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.addByNo(hero1);
        singleLinkedList.addByNo(hero4);
        singleLinkedList.addByNo(hero2);
        singleLinkedList.addByNo(hero3);
        // 显示链表内容
        singleLinkedList.linkList();
        // 测试修改
        HeroNode hero5 = new HeroNode(2, "李青","瞎子");
        singleLinkedList.update(hero5);
        System.out.println("修改后的链表:");
        singleLinkedList.linkList();
    }


运行结果:


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='无双剑姬'}
Process finished with exit code 0


继续修改一个不存在的结点:HeroNode hero5 = new HeroNode(11, "李青","瞎子");


测试结果:


HeroNode{no=1, name='易大师', nickname='无极剑圣'}
HeroNode{no=2, name='李青', nickname='盲僧'}
HeroNode{no=3, name='艾希', nickname='寒冰射手'}
HeroNode{no=4, name='菲奥娜', nickname='无双剑姬'}
未找到编号11的结点,不可修改
修改后的链表:
HeroNode{no=1, name='易大师', nickname='无极剑圣'}
HeroNode{no=2, name='李青', nickname='盲僧'}
HeroNode{no=3, name='艾希', nickname='寒冰射手'}
HeroNode{no=4, name='菲奥娜', nickname='无双剑姬'}
Process finished with exit code 0


二、单链表的删除


1、删除结点


要删除结点,依然要先找到这个结点。


1268169-20210321211424309-229454770.png


如图所示,我要删除结点4,借助temp来遍历,找到要删除的结点。但是,temp不能指在结点4,得指向结点4的前一个。


因为这是个单向链表,结点4里记录的是下一个结点的位置信息,所以在结点4这是删不掉的。应该指在结点1,这样就可以

修改结点1的next指针,绕过结点4,指向结点8。


而此时的结点4,由于没有其他引用指向它,于是被垃圾回收机制回收,到此就完成了结点4的删除了。


继续用代码来模拟,新增一个结点删除的方法:


// 删除结点
    public void delete(int no) {
        HeroNode temp = headNode;
        boolean flag = false;  // 标记是否找到待删除的结点的前一个结点
        while (true) {
            if (temp.next == null) {
                break;
            }
            if (temp.next.no == no) {
                // 找到待删除结点的前一个结点
                flag = true;
                break;
            }
            temp = temp.next; // temp后移操作
        }
        if (flag) {
            temp.next = temp.next.next;
        } else {
            System.out.printf("要删除的结点%d 不存在\n", no);
        }
    }


测试删除,我把首尾的1和4删掉。


删除后的链表:
HeroNode{no=2, name='李青', nickname='瞎子'}
HeroNode{no=3, name='艾希', nickname='寒冰射手'}
Process finished with exit code 0


我把链表里的结点全删掉:


删除后的链表:
链表为空
Process finished with exit code 0


2种情况的结果都符合预期。


三、单链表结构与顺序存储结构的优缺点


  1. 查找


单链表时间复杂度为O(n),而顺序存储结构则是O(1),更有优势。


2.插入和删除


顺序结构平均需要移动表长的一半的元素,时间复杂度为0(n)。


而单链表在找到目标位置后,插入和删除操作的时间复杂度是O(1),效率更高。


没有完美的方案,都有自己的优势,所以具体还是要根据实际需求来定。


比如说,需求是高频查找,增删很少,顺序结构更适合。反之,单链表结构更合适。

相关文章
|
1月前
|
算法
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
【❤️算法笔记❤️】-每日一刷-19、删除链表的倒数第 N个结点
69 1
|
1月前
|
算法 索引
❤️算法笔记❤️-(每日一刷-141、环形链表)
❤️算法笔记❤️-(每日一刷-141、环形链表)
46 0
|
1月前
|
算法
【❤️算法笔记❤️】-(每日一刷-876、单链表的中点)
【❤️算法笔记❤️】-(每日一刷-876、单链表的中点)
44 0
|
1月前
|
算法
【❤️算法笔记❤️】-每日一刷-23、合并 K 个升序链表
【❤️算法笔记❤️】-每日一刷-23、合并 K 个升序链表
32 0
|
1月前
|
存储 算法
【❤️算法笔记❤️】-每日一刷-21、合并两个有序链表
【❤️算法笔记❤️】-每日一刷-21、合并两个有序链表
93 0
|
23天前
|
算法 安全 搜索推荐
2024重生之回溯数据结构与算法系列学习之单双链表精题详解(9)【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构王道第2.3章之IKUN和I原达人之数据结构与算法系列学习x单双链表精题详解、数据结构、C++、排序算法、java、动态规划你个小黑子;这都学不会;能不能不要给我家鸽鸽丢脸啊~除了会黑我家鸽鸽还会干嘛?!!!
|
23天前
|
存储 Web App开发 算法
2024重生之回溯数据结构与算法系列学习之单双链表【无论是王道考研人还是IKUN都能包会的;不然别给我家鸽鸽丢脸好嘛?】
数据结构之单双链表按位、值查找;[前后]插入;删除指定节点;求表长、静态链表等代码及具体思路详解步骤;举例说明、注意点及常见报错问题所对应的解决方法
|
1月前
|
存储 缓存 算法
经典算法之链表篇(三)
经典算法之链表篇(三)
|
1月前
|
算法
经典算法之链表篇(二)
经典算法之链表篇(二)
|
1月前
|
算法 索引
经典算法之链表篇
经典算法之链表篇