// 拆分链表
ListNode* splitList(ListNode* head) {
if (head == NULL || head->next == NULL) {
return head; // 如果链表为空或只有一个节点,直接返回
}
ListNode *p1 = head; // L1 的当前节点
ListNode *p2 = NULL; // L2 的头节点
ListNode *prev2 = NULL; // L2 的前一个节点
// 遍历链表
while (p1 != NULL && p1->next != NULL) {
if (p1->next->next == NULL) { // 如果下一个节点是最后一个节点,特殊处理
// 因为下一个节点是奇数序号,直接返回,无需拆分
break;
}
// 偶数序号节点
ListNode *temp = p1->next;
p1->next = temp->next; // 从 L1 中移除偶数序号节点
// 将偶数序号节点添加到 L2
temp->next = p2; // 插入到 L2 的头部
p2 = temp;
// 如果 L2 之前已有节点,更新 prev2
if (prev2 != NULL) {
prev2 = prev2->next;
}
// 移动 L1 的指针
p1 = p1->next;
}
return p2; // 返回 L2 的头节点
}
第二:
// 拆分链表的函数
LinkedList DisUnion(LinkedList *L1, LinkedList *L2) {
*L2 = NULL; // 初始化 L2 为空链表
if (*L1 == NULL || (*L1)->next == NULL) {
// 如果 L1 为空或只有一个节点,则无需拆分
return *L1;
}
LNode *prev_L1 = *L1; // L1 的前一个节点指针,用于链接奇数节点
LNode *prev_L2 = NULL; // L2 的前一个节点指针,用于链接偶数节点
LNode *current = (*L1)->next; // 从 L1 的第二个节点开始遍历
int is_even = 0; // 标志位,表示当前是否处理偶数节点
while (current != NULL) {
LNode *next = current->next; // 保存当前节点的下一个节点
if (is_even) {
// 如果是偶数节点,将其从 L1 中移除,并添加到 L2
prev_L1->next = next; // 从 L1 中移除当前节点
current->next = *L2; // 将当前节点链接到 L2 的开头
*L2 = current; // 更新 L2 的头节点
prev_L2 = current; // 更新 L2 的前一个节点
} else {
// 如果是奇数节点,保留在 L1 中
prev_L1 = current;
}
// 切换 is_even 的值,准备处理下一个节点的奇偶性
is_even = !is_even;
current = next; // 移动到下一个节点
}
// 如果 L2 不为空,设置其尾节点的 next 为 NULL
if (prev_L2 != NULL) {
prev_L2->next = NULL;
}
// 返回 L1 的头节点(它现在只包含奇数节点)
return *L1;
}
第三:
// LinkedListDisUnion 函数接受两个链表 L1 和 L2 的指针
LinkedList DisUnion(LinkedList *L1, LinkedList *L2){
// 定义计数器 i 来跟踪当前节点的序号
int i = 0;
// 这里试图为 L2 分配内存,但这样做是不必要的,因为 L2 已经作为参数传入,且应当被初始化为一个空链表
// 这里应该是为了初始化 L2 的头节点,但更好的做法是在函数外部或函数内部以不同的方式处理
L2 = (LNode*)malloc(sizeof(LNode)); // 潜在问题:这里假设了 LNode 是链表节点的类型,但通常我们不会这样初始化链表头
L2->next = NULL; // 初始化 L2 的 next 指针为 NULL
LNode *p = L1->next; // 从 L1 的第二个节点开始遍历
LNode *pre = L1; // pre 指向 L1 的当前节点的前一个节点
while (p) { // 遍历 L1 的节点
i++; // 增加计数器
if (i % 2) { // 如果是奇数序号
// 奇数序号结点存在 L1 中,无需特别操作,只需更新 pre 和 p
pre->next = p;
pre = p;
p = p->next;
}
else { // 如果是偶数序号
// 这里应该先将 p 从 L1 中移除,但代码直接跳过了这一步
// 假设 s 是 p 的下一个节点,但 s 并未在代码中定义
LNode *s = p->next;
// 这里尝试将 p 添加到 L2,但 p->next 的赋值是错误的,并且没有更新 L2 的尾节点
p-next 应该是 p->next,但更好的是 p->next = s;
p->next = L2->next; // 这里不应该修改 p->next,而是应该让 p 成为 L2 的新节点
L2->next = p; // 这部分是正确的,但可能需要先处理 p 的 next 指针
p = s; // 这里假设了 s 已经被定义,并且是正确的下一个节点
}
}
}