写算法将单链表L1拆成二个链表,L1为头的链表保持原来向后的链表的连接。另一个链表的头为L2,其链接方向与L1相反,L1包含原链表的奇数序号的结点,L2包含原链表的偶数序号的结点

// 拆分链表  
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 已经被定义,并且是正确的下一个节点  
           
        }  
    }  
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值