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

C语言链表元素迁移问题:将左侧链表首元素移至右侧链表末尾

C语言实现左侧链表首元素移至右侧链表末尾功能

没问题,我来帮你搞定这个需求!咱们从基础的结构体定义开始,一步步实现核心功能,还会附上完整的测试代码方便你验证。

1. 定义链表节点结构体

首先咱们先把存储数据的结构体定义好,这里假设你要存的是int类型数据——如果是其他类型(比如字符串、自定义结构体),直接把data的类型替换掉就行:

// 链表节点结构体,存储数据和后继指针
typedef struct Node {
    int data;  // 替换成你实际需要存储的数据类型
    struct Node* next;
} Node;

2. 核心移动函数实现

接下来是关键的移动逻辑:把左侧链表的第一个节点移到右侧链表的末尾。这里要注意几种边界情况,比如左侧链表为空、右侧链表为空的处理,还要避免野指针问题:

// 将左侧链表的首个元素移至右侧链表末尾
// 参数用二级指针是因为要修改外部的链表头指针
void moveFirstToRight(Node** leftHead, Node** rightHead) {
    // 左侧链表为空的话直接返回,啥也干不了
    if (*leftHead == NULL) {
        printf("左侧链表为空,无法执行移动操作!\n");
        return;
    }

    // 步骤1:取出左侧链表的首节点
    Node* movedNode = *leftHead;
    // 步骤2:更新左侧链表的头指针,指向原首节点的下一个节点
    *leftHead = (*leftHead)->next;

    // 步骤3:把取出的节点挂到右侧链表的末尾
    if (*rightHead == NULL) {
        // 如果右侧链表是空的,直接把这个节点作为右侧的新头
        *rightHead = movedNode;
        movedNode->next = NULL;  // 必须置空,防止野指针
    } else {
        // 遍历右侧链表找到最后一个节点
        Node* temp = *rightHead;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        // 将新节点挂到最后一个节点的后继位置
        temp->next = movedNode;
        movedNode->next = NULL;
    }
}

3. 完整测试代码

下面是一个可以直接编译运行的完整示例,包含链表创建、打印、移动和内存释放的逻辑,你可以直接跑起来看效果:

#include <stdio.h>
#include <stdlib.h>

typedef struct Node {
    int data;
    struct Node* next;
} Node;

// 创建一个新的链表节点
Node* createNode(int data) {
    Node* newNode = (Node*)malloc(sizeof(Node));
    newNode->data = data;
    newNode->next = NULL;
    return newNode;
}

// 打印链表内容,方便查看状态
void printList(Node* head, const char* listName) {
    printf("%s链表:", listName);
    Node* temp = head;
    while (temp != NULL) {
        printf("%d ", temp->data);
        temp = temp->next;
    }
    printf("\n");
}

// 移动函数(和上面的一样)
void moveFirstToRight(Node** leftHead, Node** rightHead) {
    if (*leftHead == NULL) {
        printf("左侧链表为空,无法执行移动操作!\n");
        return;
    }

    Node* movedNode = *leftHead;
    *leftHead = (*leftHead)->next;

    if (*rightHead == NULL) {
        *rightHead = movedNode;
        movedNode->next = NULL;
    } else {
        Node* temp = *rightHead;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        temp->next = movedNode;
        movedNode->next = NULL;
    }
}

int main() {
    // 构建初始左侧链表:1 -> 2 -> 3
    Node* leftHead = createNode(1);
    leftHead->next = createNode(2);
    leftHead->next->next = createNode(3);

    // 右侧链表初始为空
    Node* rightHead = NULL;

    printf("=== 初始状态 ===\n");
    printList(leftHead, "左侧");
    printList(rightHead, "右侧");

    // 第一次移动
    moveFirstToRight(&leftHead, &rightHead);
    printf("\n=== 第一次移动后 ===\n");
    printList(leftHead, "左侧");
    printList(rightHead, "右侧");

    // 第二次移动
    moveFirstToRight(&leftHead, &rightHead);
    printf("\n=== 第二次移动后 ===\n");
    printList(leftHead, "左侧");
    printList(rightHead, "右侧");

    // 第三次移动
    moveFirstToRight(&leftHead, &rightHead);
    printf("\n=== 第三次移动后 ===\n");
    printList(leftHead, "左侧");
    printList(rightHead, "右侧");

    // 尝试移动空的左侧链表
    moveFirstToRight(&leftHead, &rightHead);

    // 记得释放内存,避免内存泄漏
    Node* temp;
    while (rightHead != NULL) {
        temp = rightHead;
        rightHead = rightHead->next;
        free(temp);
    }

    return 0;
}

4. 关键注意点

  • 数据类型适配:如果你的结构体存储的不是int,只需要修改data的类型,其他逻辑完全通用。
  • 野指针防范:移动节点后一定要把movedNode->next置为NULL,否则可能导致右侧链表出现循环或者非法内存访问。
  • 内存管理:实际项目中别忘了释放链表节点的内存,避免内存泄漏。
  • 指针参数:函数用二级指针是因为要修改外部的链表头指针——如果只用一级指针,函数内部的修改不会影响到外部的指针变量。

内容的提问来源于stack exchange,提问作者Ania

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 04:11:11