当前位置:   article > 正文

重排链表 C语言_c语言 单链表重新排列

c语言 单链表重新排列

题目描述:

给定一个单链表 L 的头节点 head ,单链表 L 表示为:

L0 → L1 → … → Ln-1 → Ln
请将其重新排列后变为:

L0 → Ln → L1 → Ln-1 → L2 → Ln-2 → …

不能只是单纯的改变节点内部的值,而是需要实际的进行节点交换。

示例:

  • 输入: head = [1,2,3,4]
    输出: [1,4,2,3]
  • 输入: head = [1,2,3,4,5]
    输出: [1,5,2,4,3]

解题思路:

寻找中间结点 + 链表逆转 + 合并链表

1.找到链表的中间结点,利用快慢指针法寻找中间结点
2. 将原链表的右半部分链表逆转
3. 将两链表合并`


/*
解题思路:
先找到中间结点,分割成两个新的链表,然后对右侧的链表进行反转,再重新连接两个链表即可
*/
//逆转链表
struct ListNode *reverse(struct ListNode *head)
{
    if(head == NULL || head->next == NULL)
        return head;
    struct ListNode *newHead = reverse(head->next);
    head->next->next = head;
    head->next = NULL;
    return newHead;
}

void reorderList(struct ListNode* head){
    if(head == NULL || head->next == NULL)
        return head;
    struct ListNode *left = head,*right = head;
    while(right && right->next)
    {
        left = left->next;
        right = right->next->next;
    }
    //此时left指向中间的结点
    struct ListNode leftHead,rightHead;      //使用两个新的头结点
    leftHead.next = head;
    rightHead.next = left->next;
    left->next = NULL;          //更新中间结点的后继结点
    rightHead.next = reverse(rightHead.next);    //反转右侧链表
    left = leftHead.next;
    right = rightHead.next;     //更新指针位置
    struct ListNode *p=&leftHead;
    while(left && right)
    {
        p->next = left;
        left = left->next;
        p=p->next;
        p->next = right;
        right=right->next;
        p=p->next;
    }
    p->next = left?left:right;//指针p的后继指向 left 和 right 中不空的那个结点
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/笔触狂放9/article/detail/226637
推荐阅读
相关标签
  

闽ICP备14008679号