返回

链表旋转:突破循环的技巧和窍门

闲谈

旋转链表:从旋转的角度看世界

在计算机科学中,链表是一种常见的数据结构。它由一系列连接在一起的节点组成,每个节点存储一个值和一个指向下一个节点的指针。链表可以用来表示各种数据,如列表、队列和栈。

旋转链表是一种将链表中的每个节点向右移动一定数量的步骤的操作。这种操作在某些情况下非常有用,例如,当我们需要将链表中的最后一个元素移动到第一个元素时。

旋转链表的算法

旋转链表的算法非常简单。它可以分为以下几个步骤:

  1. 找到链表的最后一个节点。
  2. 将最后一个节点的指针指向链表的第一个节点。
  3. 将链表的第一个节点的指针指向链表的第二个节点。
  4. 重复步骤3,直到链表的最后一个节点的指针指向链表的第一个节点。

旋转链表的代码实现

以下是用C++实现的旋转链表的代码:

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

ListNode* rotateRight(ListNode* head, int k) {
    if (head == NULL || head->next == NULL) {
        return head;
    }

    // 找到链表的最后一个节点
    ListNode *tail = head;
    while (tail->next != NULL) {
        tail = tail->next;
    }

    // 将最后一个节点的指针指向链表的第一个节点
    tail->next = head;

    // 将链表的第一个节点的指针指向链表的第二个节点
    ListNode *newHead = head->next;
    head->next = NULL;

    // 重复步骤3,直到链表的最后一个节点的指针指向链表的第一个节点
    for (int i = 0; i < k - 1; i++) {
        newHead = newHead->next;
    }

    // 将链表的最后一个节点的指针指向链表的第一个节点
    tail = newHead->next;
    newHead->next = NULL;

    return tail;
}

用Python实现的代码如下:

class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

def rotateRight(head, k):
    if not head or not head.next:
        return head

    # 找到链表的最后一个节点
    tail = head
    while tail.next:
        tail = tail.next

    # 将最后一个节点的指针指向链表的第一个节点
    tail.next = head

    # 将链表的第一个节点的指针指向链表的第二个节点
    newHead = head.next
    head.next = None

    # 重复步骤3,直到链表的最后一个节点的指针指向链表的第一个节点
    for _ in range(k - 1):
        newHead = newHead.next

    # 将链表的最后一个节点的指针指向链表的第一个节点
    tail = newHead.next
    newHead.next = None

    return tail

用Java实现的代码如下:

public class Solution {
    public ListNode rotateRight(ListNode head, int k) {
        if (head == null || head.next == null) {
            return head;
        }

        // 找到链表的最后一个节点
        ListNode tail = head;
        while (tail.next != null) {
            tail = tail.next;
        }

        // 将最后一个节点的指针指向链表的第一个节点
        tail.next = head;

        // 将链表的第一个节点的指针指向链表的第二个节点
        ListNode newHead = head.next;
        head.next = null;

        // 重复步骤3,直到链表的最后一个节点的指针指向链表的第一个节点
        for (int i = 0; i < k - 1; i++) {
            newHead = newHead.next;
        }

        // 将链表的最后一个节点的指针指向链表的第一个节点
        tail = newHead.next;
        newHead.next = null;

        return tail;
    }
}

结语

旋转链表是一种非常简单的算法。通过旋转链表,我们可以实现一些非常有趣的功能。例如,我们可以将链表中的最后一个元素移动到第一个元素,也可以将链表中的第一个元素移动到最后一个元素。旋转链表算法在很多领域都有着广泛的应用,例如,在数据结构、算法和操作系统等领域。