链表-单链表【node2】

基础结构

// 链表节点内部类
static class Node {
    String data;  // 节点存储的数据(使用String类型,与Python示例一致)
    Node next;    // 指向下一个节点的引用

    // 节点构造方法
    public Node(String data) {
        this.data = data;
        this.next = null;
    }
}

private Node head;  // 链表头节点

// 单链表构造方法
public SinglyLinkedList() {
    this.head = null;
}

插入

单链表的插入操作有三种情况:头部插入、中间插入和尾部插入

头部插入

将新节点的next指向当前的头节点,然后将头节点更新为新节点。

算法步骤:

1. 创建新节点
2. 将新节点的next指向当前的头节点
3. 更新头节点为新节点

/**
 * 头部添加节点(头插法)
 * @param data 插入的数据
 */
public void prepend(String data) {
    Node newNode = new Node(data);
    // 将新节点的next指向当前的头节点
    newNode.next = head;
    // 更新头节点为新节点
    head = newNode;
}
尾部插入

遍历链表找到最后一个节点,然后将最后一个节点的next指向新节点。

算法步骤:

1. 创建新节点
2. 如果链表为空,将新节点设为头节点
3. 否则,遍历到链表末尾
4. 将最后一个节点的next指向新节点

/**
 * 尾部添加节点(尾插法)
 * @param data 插入的数据
 */
public void append(String data) {
    Node newNode = new Node(data);

    // 如果链表为空,将新节点设为头节点
    if (head == null) {
        head = newNode;
        return;
    }

    // 遍历到链表末尾
    Node current = head;
    while (current.next != null) {
        current = current.next;
    }

    // 将新节点链接到末尾
    current.next = newNode;
}
指定位置插入

将新节点的next指向目标节点的next,然后将目标节点的next指向新节点。

算法步骤:

1. 创建新节点
2. 将新节点的next指向目标节点的next
3. 将目标节点的next指向新节点

/**
 * 在指定节点后添加新节点
 * @param prevNode 指定的前一个节点
 * @param data 插入的数据
 */
public void insertAfterNode(Node prevNode, String data) {
    // 检查前一个节点是否存在
    if (prevNode == null) {
        System.out.println("前一个节点不存在");
        return;
    }

    Node newNode = new Node(data);
    // 将新节点的next指向前一个节点的next
    newNode.next = prevNode.next;
    // 将前一个节点的next指向新节点
    prevNode.next = newNode;
}

删除

查找要删除的节点,并将其前一个节点的next指向要删除节点的next。

算法步骤:

1. 如果头节点是要删除的节点,直接将头节点更新为下一个节点
2. 否则,遍历链表找到要删除的节点及其前一个节点
3. 将前一个节点的next指向要删除节点的next
4. 释放要删除的节点

/**
 * 删除包含特定值的节点
 * @param key 要删除的节点值
 */
public void deleteNode(String key) {
    // 保存当前节点
    Node current = head;

    // 如果头节点包含要删除的值
    if (current != null && current.data.equals(key)) {
        head = current.next;
        current = null;
        return;
    }

    // 搜索要删除的节点
    Node prev = null;
    while (current != null && !current.data.equals(key)) {
        prev = current;
        current = current.next;
    }

    // 如果没有找到要删除的节点
    if (current == null) {
        return;
    }

    // 将前一个节点的next跳过当前节点指向下一个节点
    prev.next = current.next;
    current = null;
}
/**
 * 按位置删除节点
 * @param position 要删除的节点位置(从0开始)
 */
public void deleteAtPos(int position) {
    if (head == null) {
        return;
    }

    // 如果删除头节点
    if (position == 0) {
        head = head.next;
        return;
    }

    Node current = head;
    for (int i = 0; i < position - 1; i++) {
        if (current == null || current.next == null) {
            return;
        }
        current = current.next;
    }

    // 如果到达链表末尾
    if (current == null || current.next == null) {
        return;
    }

    // 删除current.next节点
    Node nextNode = current.next.next;
    current.next = nextNode;
}

查找

遍历链表查找特定值的节点。

算法步骤:

1. 从头节点开始遍历链表
2. 检查每个节点的数据是否等于目标值
3. 如果找到,返回True
4. 如果遍历完整个链表都没找到,返回False

/**
 * 查找包含特定值的节点
 * @param key 要查找的值
 * @return 是否找到
 */
public boolean search(String key) {
    Node current = head;
    while (current != null) {
        if (current.data.equals(key)) {
            return true;
        }
        current = current.next;
    }
    return false;
}

更新

查找特定值的节点并更新其数据。

算法步骤:

1. 从头节点开始遍历链表
2. 检查每个节点的数据是否等于目标值
3. 如果找到,更新节点数据并返回True
4. 如果遍历完整个链表都没找到,返回False

/**
 * 更新节点值
 * @param key 要更新的旧值
 * @param newData 新值
 * @return 是否更新成功
 */
public boolean updateNode(String key, String newData) {
    Node current = head;
    while (current != null) {
        if (current.data.equals(key)) {
            current.data = newData;
            return true;
        }
        current = current.next;
    }
    return false;
}

遍历

从头节点开始遍历链表

/**
 * 打印链表
 */
public void printList() {
    Node current = head;
    while (current != null) {
        System.out.print(current.data + " -> ");
        current = current.next;
    }
    System.out.println("null");
}

完整代码

/**
 * @Author Stringzhua
 * @Date 2025/10/23 14:51
 * description:
 */
public class SinglyLinkedList {
    // 链表节点内部类
    static class Node {
        String data;  // 节点存储的数据(使用String类型,与Python示例一致)
        Node next;    // 指向下一个节点的引用

        // 节点构造方法
        public Node(String data) {
            this.data = data;
            this.next = null;
        }
    }

    private Node head;  // 链表头节点

    // 单链表构造方法
    public SinglyLinkedList() {
        this.head = null;
    }

    /**
     * 尾部添加节点(尾插法)
     * @param data 插入的数据
     */
    public void append(String data) {
        Node newNode = new Node(data);

        // 如果链表为空,将新节点设为头节点
        if (head == null) {
            head = newNode;
            return;
        }

        // 遍历到链表末尾
        Node current = head;
        while (current.next != null) {
            current = current.next;
        }

        // 将新节点链接到末尾
        current.next = newNode;
    }

    /**
     * 头部添加节点(头插法)
     * @param data 插入的数据
     */
    public void prepend(String data) {
        Node newNode = new Node(data);
        // 将新节点的next指向当前的头节点
        newNode.next = head;
        // 更新头节点为新节点
        head = newNode;
    }

    /**
     * 在指定节点后添加新节点
     * @param prevNode 指定的前一个节点
     * @param data 插入的数据
     */
    public void insertAfterNode(Node prevNode, String data) {
        // 检查前一个节点是否存在
        if (prevNode == null) {
            System.out.println("前一个节点不存在");
            return;
        }

        Node newNode = new Node(data);
        // 将新节点的next指向前一个节点的next
        newNode.next = prevNode.next;
        // 将前一个节点的next指向新节点
        prevNode.next = newNode;
    }

    /**
     * 删除包含特定值的节点
     * @param key 要删除的节点值
     */
    public void deleteNode(String key) {
        // 保存当前节点
        Node current = head;

        // 如果头节点包含要删除的值
        if (current != null && current.data.equals(key)) {
            head = current.next;
            current = null;
            return;
        }

        // 搜索要删除的节点
        Node prev = null;
        while (current != null && !current.data.equals(key)) {
            prev = current;
            current = current.next;
        }

        // 如果没有找到要删除的节点
        if (current == null) {
            return;
        }

        // 将前一个节点的next跳过当前节点指向下一个节点
        prev.next = current.next;
        current = null;
    }

    /**
     * 按位置删除节点
     * @param position 要删除的节点位置(从0开始)
     */
    public void deleteAtPos(int position) {
        if (head == null) {
            return;
        }

        // 如果删除头节点
        if (position == 0) {
            head = head.next;
            return;
        }

        Node current = head;
        for (int i = 0; i < position - 1; i++) {
            if (current == null || current.next == null) {
                return;
            }
            current = current.next;
        }

        // 如果到达链表末尾
        if (current == null || current.next == null) {
            return;
        }

        // 删除current.next节点
        Node nextNode = current.next.next;
        current.next = nextNode;
    }

    /**
     * 查找包含特定值的节点
     * @param key 要查找的值
     * @return 是否找到
     */
    public boolean search(String key) {
        Node current = head;
        while (current != null) {
            if (current.data.equals(key)) {
                return true;
            }
            current = current.next;
        }
        return false;
    }

    /**
     * 更新节点值
     * @param key 要更新的旧值
     * @param newData 新值
     * @return 是否更新成功
     */
    public boolean updateNode(String key, String newData) {
        Node current = head;
        while (current != null) {
            if (current.data.equals(key)) {
                current.data = newData;
                return true;
            }
            current = current.next;
        }
        return false;
    }

    /**
     * 打印链表
     */
    public void printList() {
        Node current = head;
        while (current != null) {
            System.out.print(current.data + " -> ");
            current = current.next;
        }
        System.out.println("null");
    }

    public static void main(String[] args) {
        // 创建一个空链表
        SinglyLinkedList linkedList = new SinglyLinkedList();

        // 在末尾添加节点
        linkedList.append("A");
        linkedList.append("B");
        linkedList.append("C");

        System.out.println("原始链表:");
        linkedList.printList();  // 输出: A -> B -> C -> null

        // 在头部添加节点
        linkedList.prepend("X");
        System.out.println("在头部添加 'X' 后:");
        linkedList.printList();  // 输出: X -> A -> B -> C -> null

        // 在 'A' 后添加节点
        Node current = linkedList.head.next;  // 'A' 节点
        linkedList.insertAfterNode(current, "Y");
        System.out.println("在 'A' 后添加 'Y' 后:");
        linkedList.printList();  // 输出: X -> A -> Y -> B -> C -> null

        // 删除值为 'B' 的节点
        linkedList.deleteNode("B");
        System.out.println("删除值为 'B' 的节点后:");
        linkedList.printList();  // 输出: X -> A -> Y -> C -> null

        // 查找值为 'Y' 的节点
        System.out.println("查找值为 'Y' 的节点: " + linkedList.search("Y"));  // 输出: true
        System.out.println("查找值为 'B' 的节点: " + linkedList.search("B"));  // 输出: false

        // 更新值为 'Y' 的节点为 'Z'
        linkedList.updateNode("Y", "Z");
        System.out.println("更新值为 'Y' 的节点为 'Z' 后:");
        linkedList.printList();  // 输出: X -> A -> Z -> C -> null
    }
}

时间空间复杂度分析

操作时间复杂度空间复杂度说明
访问元素(按索引)O(n)O(1)不支持随机访问,必须从头节点开始遍历直到找到第n个元素
访问元素(头部)O(1)O(1)可以直接通过头指针访问头部元素
访问元素(尾部)O(n)O(1)如果没有尾指针,则需遍历整个链表;有尾指针则为O(1)
插入元素(头部)O(1)O(1)只需调整头指针和新节点的指针
插入元素(尾部)O(n)O(1)没有尾指针时需要遍历到尾部;有尾指针则为O(1)
插入元素(中间)O(n)O(1)需要先找到插入位置(O(n)),然后调整指针(O(1))
删除元素(头部)O(1)O(1)只需调整头指针让它指向第二个节点
删除元素(尾部)O(n)O(1)需要遍历到倒数第二个节点将其next指针置空
删除元素(中间)O(n)O(1)需要找到目标节点的前一个节点(O(n)),然后调整指针(O(1))
查找元素O(n)O(1)最坏情况下需要遍历整个链表
更新元素O(n)O(1)先查找(O(n))再更新(O(1))
遍历O(n)O(1)从头到尾访问每个节点一次
内容概要:本文系统研究了全桥LLC谐振变换器的脉冲频率调制(PFM)控制策略,深入剖析其拓扑结构与工作原理,涵盖全桥逆变电路、谐振回路(Lr、Cr、Lm)、变压器及整流滤波电路的功能与协同机制。文章详细分析了变换器在不同开关频率下的三种工作模式(fs > fr、fs = fr、fm < fs < fr),阐明了其在感性区域实现原边零电压开通(ZVS)和副边零电流关断(ZCS)的软开关特性。重点阐述了PFM控制通过调节开关频率来改变谐振阻抗,从而稳定输出电压的基本原理,并论证了其在高效率(尤其轻载时)、低电磁干扰(EMI)和宽输入输出范围方面的显著优势。研究构建了基于Matlab/Simulink的完整仿真模型,对系统的稳态性能、动态响应(负载突变)和效率进行了全面仿真验证,结果证实PFM控制能有效实现输出电压的精确稳定,具备优良的动态响应能力和全负载范围内的高效率。最后,文章总结了PFM策略的有效性,并展望了结合自抗扰控制(ADRC)等先进算法优化控制性能及开展硬件实验验证的未来发展方向。; 适合人群:具备电力电子、自动控制或相关领域基础知识的研究生、科研人员及从事高性能电源设计的工程技术人员。; 使用场景及目标:①深入理解LLC谐振变换器的拓扑结构、工作模式划分及其软开关物理机制;②掌握PFM控制策略的设计思想、参数整定方法及其在提升电源转换效率与降低EMI中的核心应用;③为开发高效率、高可靠性的开关电源(如通信电源、服务器电源)提供理论依据、仿真建模指导与性能优化的技术参考。; 阅读建议:在阅读时应紧密结合文中给出的仿真模型框图与关键波形,重点精读工作模式分析与PFM控制原理部分,建议动手复现仿真以深刻体会频率调节对增益和效率的影响规律,并特别关注轻载效率表现,同时思考未来展望中提及的先进控制算法融合方向,以激发创新研究思路。
内容概要:本文系统介绍了基于Matlab的多架无人机编队控制与轨迹规划技术实现方案,聚焦于一致性分布式控制、多领航者架构、编队跟随控制及轨迹跟踪等核心算法的建模与仿真。通过Matlab代码实现了多无人机系统的编队形成、保持与动态调整,并融合RRT、人工势场法、粒子群优化(PSO)、Q-learning等智能算法,完成复杂环境下的路径规划与避障任务。文档还深入探讨了滑模控制、反步法、模型预测控制(MPC)等多种先进控制策略在无人机协同中的应用,展现了系统在动态干扰和不确定环境下的鲁棒性与自适应能力。配套提供的完整Matlab代码涵盖多种编队模式与控制算法对比案例,支持二次开发与性能验证。; 适合人群:具备自动控制理论基础和Matlab编程能力的科研人员、研究生及从事无人机系统开发的工程技术人员,尤其适用于研究多智能体协同控制、分布式编队与自主路径规划方向的专业人士。; 使用场景及目标:① 实现多无人机在复杂动态环境中的高效协同飞行与稳定编队;② 解决队形切换、轨迹实时优化与动态障碍物规避等关键问题;③ 为学术研究、毕业设计或实际工程项目提供可复现的算法框架与仿真平台支持; 其他说明:文中所有Matlab仿真代码可通过指定百度网盘链接下载,建议结合仿真运行深入理解算法细节,并根据具体应用场景进行参数调优与算法拓展。
内容概要:本文研究基于动态非合作博弈的大规模电动汽车实时优化调度决策方法,通过构建博弈论模型刻画电动汽车用户间的竞争行为,利用Matlab实现算法仿真与求解。研究将复杂的充电调度问题建模为动态非合作博弈形式,分析各电动汽车作为理性个体在电网负荷、电价及用户偏好等多重约束下的最优充放电策略,实现去中心化、分布式的实时调度优化。结合动态博弈理论与电力系统运行特性,文章深入探讨了纳什均衡的存在性、唯一性及迭代求解的收敛性,并通过仿真实验验证该方法在平抑电网负荷峰值、降低用户用电成本、提升可再生能源消纳能力以及增强电网运行稳定性方面的综合效益。; 适合人群:具备博弈论、优化理论、电力系统基础及相关数学建模能力,从事智能电网、电动汽车调度、能源互联网、车网互动(V2G)等方向研究的研究生、科研人员及工程技术人员。; 使用场景及目标:①应用于大规模电动汽车接入背景下的实时需求响应与分布式调度系统设计;②为电力公司制定动态电价机制、激励策略及负荷管理政策提供理论依据与技术支持;③促进车网互动技术的实际落地,推动新型电力系统中用户侧资源的高效协同与优化利用; 阅读建议:读者应结合提供的Matlab代码深入理解模型构建与算法实现细节,重点关注博弈模型的效用函数设计、约束条件处理、均衡求解过程及仿真参数设置,建议使用真实或模拟数据进行复现与拓展实验,以全面掌握其应用逻辑与优化潜力。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值