C语言编程--21.两两交换链表中的结点
C语言编程–21.两两交换链表中的结点
题目:
给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。
示例 1:
输入:head = [1,2,3,4]
输出:[2,1,4,3]
示例 2:
输入:head = []
输出:[]
示例 3:
输入:head = [1]
输出:[1]
提示:
链表中节点的数目在范围 [0, 100] 内
0 <= Node.val <= 100
/*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/
struct ListNode* swapPairs(struct ListNode* head) {// 处理空链表或只有一个节点的情况,直接返回头指针if(head == NULL || head->next == NULL)return head;// 初始交换前两个节点struct ListNode* temp = head->next->next; // 保存第三个节点struct ListNode* h = head->next; // 新的头节点变为原第二个节点h->next = head; // 新头节点指向原头节点struct ListNode* tail = h->next; // tail指向当前的第一个节点(原头节点)tail->next = temp; // 连接到第三个节点(跳过原第二个节点)// 循环交换剩余的节点对while(tail->next && tail->next->next) {// 定位当前需要交换的两个节点struct ListNode* left = tail->next->next; // 指向当前节点对的第二个节点temp = left->next; // 保存下一对的第一个节点// 执行交换操作left->next = tail->next; // 第二个节点指向第一个节点tail->next = left; // 前一个节点对的尾节点指向新的头节点tail = left->next; // tail移动到当前节点对的尾节点tail->next = temp; // 连接到下一对的第一个节点}return h; // 返回新的头节点
}
代码优点分析:
- 原地交换:不需要额外的存储空间,只需要常数级的额外空间。
- 直接操作指针:通过调整节点的指针域实现交换,效率较高。
- 处理边界条件:函数开始时检查了链表是否为空或只有一个节点的情况。
- 单次遍历:算法时间复杂度为 O (n),只需要遍历一次链表。
代码缺点分析
- 逻辑复杂:指针操作较多,代码可读性较差,容易出错。
- 初始处理特殊:前两个节点的交换逻辑与后续节点对的交换逻辑不一致,增加了理解难度。
- 可维护性低:如果需要扩展功能(如交换 k 个节点为一组),现有结构难以复用。