You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何交换循环链表的前后两半?CLList类swapHalf()实现求助

循环链表swapHalf()函数实现问题

在CLList类中编写一个名为swapHalf()的函数,用于交换循环链表的前半部分与后半部分,需覆盖所有边界情况。
示例:
交换前:[v,w,t,j,q,o,w,s,w,t]
调用swapHalf()后:
交换后:[o,w,s,w,t,v,w,t,j,q]

我目前只能处理链表长度为0或2的情况,但处理长度为2的情况时会丢失元素,不知道如何适配任意长度的循环链表:

public void swapHalf() {
    CharNode cn;
    if (tail == null) {
        return;
    } else if (tail == tail.next.next) {
         cn = tail;
         cn.setNext(tail);
         cn.next.setNext(tail.next);
    }
}

解决思路

要实现任意长度循环链表的前后半交换,核心是定位三个关键节点,再通过调整指针完成闭环:

  1. 原链表的尾节点tail(循环链表通常用尾节点指向头节点)
  2. 前半部分的尾节点firstHalfTail
  3. 后半部分的头节点secondHalfHead

具体步骤:

  • 统计长度:遍历链表得到总节点数,长度≤1时无需交换直接返回
  • 定位节点:根据总长度找到前半部分的尾节点(总长度为size时,前半长度取size/2)
  • 调整指针:重新连接前后半部分,更新尾节点指向,保证链表循环特性

完整实现代码

public void swapHalf() {
    // 空链表或单节点链表,无需交换
    if (tail == null || tail.next == tail) {
        return;
    }

    // 统计链表总长度
    int size = 1;
    CharNode current = tail.next;
    while (current != tail) {
        size++;
        current = current.next;
    }

    // 找到前半部分的尾节点
    int halfLength = size / 2;
    CharNode firstHalfTail = tail.next;
    for (int i = 1; i < halfLength; i++) {
        firstHalfTail = firstHalfTail.next;
    }

    // 执行交换逻辑
    CharNode oldHead = tail.next;
    CharNode secondHalfHead = firstHalfTail.next;

    // 前半部分尾节点指向原头节点,形成新的后半段闭环
    firstHalfTail.next = oldHead;
    // 原尾节点指向后半部分头节点,更新链表尾节点
    tail.next = secondHalfHead;
    tail = firstHalfTail;
}

边界情况验证

  • 空链表:直接返回,无操作
  • 单节点链表:无需交换,直接返回
  • 长度2的链表:交换后节点顺序反转,循环逻辑正常(如[A,B]→[B,A])
  • 奇数长度链表:前半部分长度为size/2,后半部分更长,交换后后半段在前,符合示例的分割逻辑

内容的提问来源于stack exchange,提问作者San Dan Glokta

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 03:33:14