📜  双向链表顺时针旋转 N 个位置(1)

📅  最后修改于: 2023-12-03 15:07:22.762000             🧑  作者: Mango

双向链表顺时针旋转 N 个位置

简介

双向链表是一种常见的数据结构,每个节点除了包含一个指向下一个节点的指针外,还包含一个指向上一个节点的指针。在一些场合中,我们需要对双向链表进行顺时针旋转,本文将介绍如何实现这一操作。

思路

我们首先需要找到需要旋转的部分。假设链表的长度为len,我们需要将链表顺时针旋转N个位置,相当于将链表的后N个节点移到链表的前面,从而形成一个新的链表。

具体实现时,我们可以先将链表首尾相连,形成一个环形链表。将链表整体向右移动N个节点,就是将尾节点向右移动N个位置,头节点则向右移动N - 1个位置。此时只需要将尾节点和头节点断开,原链表就变成了顺时针旋转N个位置后的链表。

代码实现

首先我们需要定义双向链表的节点:

struct ListNode {
    int val;
    ListNode* prev;
    ListNode* next;
    ListNode(int x) : val(x), prev(nullptr), next(nullptr) {}
};

然后是顺时针旋转N个位置的代码实现:

ListNode* rotateList(ListNode* head, int k) {
    if (!head) return nullptr;

    // 计算链表长度
    int len = 1;
    ListNode* p = head;
    while (p->next) {
        len++;
        p = p->next;
    }

    // 将链表首尾相连形成环形链表
    p->next = head;
    head->prev = p;

    // 计算需要旋转的位置
    k %= len;
    if (k == 0) return head;

    // 开始旋转链表
    p = head;
    for (int i = 0; i < len - k - 1; i++) p = p->next;
    ListNode* new_head = p->next;
    new_head->prev = nullptr;
    p->next = nullptr;

    return new_head;
}
总结

顺时针旋转双向链表的操作需要我们先将链表首尾相连形成环形链表,然后对需要旋转的部分进行移动。最后再将链表断开,得到旋转后的链表。本篇文章提供了一种简单易懂的实现方式。