📜  链表顺时针旋转

📅  最后修改于: 2022-05-13 01:57:43.931000             🧑  作者: Mango

链表顺时针旋转

给定一个单向链表和一个整数K ,任务是将链表顺时针向右旋转K 个位置。
例子:

方法:旋转链表首先检查给定的 k 是否大于链表中的节点数。遍历链表,找到链表的长度然后与k比较,如果小于则继续,否则通过对链表长度取模来推导它在链表大小范围内。
之后从列表的长度中减去 k 的值。现在,问题已更改为链表的左旋转,因此请按照以下步骤操作:

  • 将第 k 个节点的下一个更改为 NULL。
  • 将最后一个节点的 next 更改为上一个头节点。
  • 将头部更改为第 (k+1) 个节点。

为此,需要指向第 k 个节点、第 (k+1) 个节点和最后一个节点的指针。
下面是上述方法的实现:



C++
// C++ implementation of the approach
#include 
using namespace std;
 
/* Link list node */
class Node {
public:
    int data;
    Node* next;
};
 
/* A utility function to push a node */
void push(Node** head_ref, int new_data)
{
    /* allocate node */
    Node* new_node = new Node();
 
    /* put in the data */
    new_node->data = new_data;
 
    /* link the old list off the new node */
    new_node->next = (*head_ref);
 
    /* move the head to point to the new node */
    (*head_ref) = new_node;
}
 
/* A utility function to print linked list */
void printList(Node* node)
{
    while (node != NULL) {
        cout << node->data << " -> ";
        node = node->next;
    }
    cout << "NULL";
}
 
// Function that rotates the given linked list
// clockwise by k and returns the updated
// head pointer
Node* rightRotate(Node* head, int k)
{
 
    // If the linked list is empty
    if (!head)
        return head;
 
    // len is used to store length of the linked list
    // tmp will point to the last node after this loop
    Node* tmp = head;
    int len = 1;
    while (tmp->next != NULL) {
        tmp = tmp->next;
        len++;
    }
 
    // If k is greater than the size
    // of the linked list
    if (k > len)
        k = k % len;
 
    // Subtract from length to convert
    // it into left rotation
    k = len - k;
 
    // If no rotation needed then
    // return the head node
    if (k == 0 || k == len)
        return head;
 
    // current will either point to
    // kth or NULL after this loop
    Node* current = head;
    int cnt = 1;
    while (cnt < k && current != NULL) {
        current = current->next;
        cnt++;
    }
 
    // If current is NULL then k is equal to the
    // count of nodes in the list
    // Don't change the list in this case
    if (current == NULL)
        return head;
 
    // current points to the kth node
    Node* kthnode = current;
 
    // Change next of last node to previous head
    tmp->next = head;
 
    // Change head to (k+1)th node
    head = kthnode->next;
 
    // Change next of kth node to NULL
    kthnode->next = NULL;
 
    // Return the updated head pointer
    return head;
}
 
// Driver code
int main()
{
 
    /* The constructed linked list is:
    1->2->3->4->5 */
    Node* head = NULL;
    push(&head, 5);
    push(&head, 4);
    push(&head, 3);
    push(&head, 2);
    push(&head, 1);
 
    int k = 2;
 
    // Rotate the linked list
    Node* updated_head = rightRotate(head, k);
 
    // Print the rotated linked list
    printList(updated_head);
 
    return 0;
}


Java
// Java implementation of the approach
class GFG
{
     
/* Link list node */
static class Node
{
    int data;
    Node next;
}
 
/* A utility function to push a node */
static Node push(Node head_ref, int new_data)
{
    /* allocate node */
    Node new_node = new Node();
 
    /* put in the data */
    new_node.data = new_data;
 
    /* link the old list off the new node */
    new_node.next = (head_ref);
 
    /* move the head to point to the new node */
    (head_ref) = new_node;
    return head_ref;
}
 
/* A utility function to print linked list */
static void printList(Node node)
{
    while (node != null)
    {
        System.out.print(node.data + " -> ");
        node = node.next;
    }
    System.out.print( "null");
}
 
// Function that rotates the given linked list
// clockwise by k and returns the updated
// head pointer
static Node rightRotate(Node head, int k)
{
 
    // If the linked list is empty
    if (head == null)
        return head;
 
    // len is used to store length of the linked list
    // tmp will point to the last node after this loop
    Node tmp = head;
    int len = 1;
    while (tmp.next != null)
    {
        tmp = tmp.next;
        len++;
    }
 
    // If k is greater than the size
    // of the linked list
    if (k > len)
        k = k % len;
 
    // Subtract from length to convert
    // it into left rotation
    k = len - k;
 
    // If no rotation needed then
    // return the head node   
    if (k == 0 || k == len)
        return head;
 
    // current will either point to
    // kth or null after this loop
    Node current = head;
    int cnt = 1;
    while (cnt < k && current != null)
    {
        current = current.next;
        cnt++;
    }
 
    // If current is null then k is equal to the
    // count of nodes in the list
    // Don't change the list in this case
    if (current == null)
        return head;
 
    // current points to the kth node
    Node kthnode = current;
 
    // Change next of last node to previous head
    tmp.next = head;
 
    // Change head to (k+1)th node
    head = kthnode.next;
 
    // Change next of kth node to null
    kthnode.next = null;
 
    // Return the updated head pointer
    return head;
}
 
// Driver code
public static void main(String args[])
{
 
    /* The constructed linked list is:
    1.2.3.4.5 */
    Node head = null;
    head = push(head, 5);
    head = push(head, 4);
    head = push(head, 3);
    head = push(head, 2);
    head = push(head, 1);
 
    int k = 2;
 
    // Rotate the linked list
    Node updated_head = rightRotate(head, k);
 
    // Print the rotated linked list
    printList(updated_head);
}
}
 
// This code is contributed by Arnub Kundu


Python3
# Python3 implementation of the approach
 
''' Link list node '''
class Node:
 
    def __init__(self, data):
        self.data = data
        self.next = None
 
''' A utility function to push a node '''
def push(head_ref, new_data):
   
    ''' allocate node '''
    new_node = Node(new_data)
 
    ''' put in the data '''
    new_node.data = new_data
 
    ''' link the old list off the new node '''
    new_node.next = (head_ref)
 
    ''' move the head to point to the new node '''
    (head_ref) = new_node
 
    return head_ref
 
''' A utility function to print linked list '''
def printList(node):
    while (node != None):
        print(node.data, end=' -> ')
        node = node.next
    print("NULL")
 
# Function that rotates the given linked list
# clockwise by k and returns the updated
# head pointer
def rightRotate(head, k):
 
    # If the linked list is empty
    if (not head):
        return head
 
    # len is used to store length of the linked list
    # tmp will point to the last node after this loop
    tmp = head
    len = 1
 
    while (tmp.next != None):
        tmp = tmp.next
        len += 1
 
    # If k is greater than the size
    # of the linked list
    if (k > len):
        k = k % len
 
    # Subtract from length to convert
    # it into left rotation
    k = len - k
 
    # If no rotation needed then
    # return the head node
    if (k == 0 or k == len):
        return head
 
    # current will either point to
    # kth or None after this loop
    current = head
    cnt = 1
 
    while (cnt < k and current != None):
        current = current.next
        cnt += 1
 
    # If current is None then k is equal to the
    # count of nodes in the list
    # Don't change the list in this case
    if (current == None):
        return head
 
    # current points to the kth node
    kthnode = current
 
    # Change next of last node to previous head
    tmp.next = head
 
    # Change head to (k+1)th node
    head = kthnode.next
 
    # Change next of kth node to None
    kthnode.next = None
 
    # Return the updated head pointer
    return head
 
 
# Driver code
if __name__ == '__main__':
 
    ''' The constructed linked list is:
    1.2.3.4.5 '''
    head = None
    head = push(head, 5)
    head = push(head, 4)
    head = push(head, 3)
    head = push(head, 2)
    head = push(head, 1)
    k = 2
 
    # Rotate the linked list
    updated_head = rightRotate(head, k)
 
    # Print the rotated linked list
    printList(updated_head)
     
    # This code is contributed by rutvik_56


C#
// C# implementation of the approach
using System;
 
class GFG
{
     
/* Link list node */
public class Node
{
    public int data;
    public Node next;
}
 
/* A utility function to push a node */
static Node push(Node head_ref,
                 int new_data)
{
    /* allocate node */
    Node new_node = new Node();
 
    /* put in the data */
    new_node.data = new_data;
 
    /* link the old list off the new node */
    new_node.next = (head_ref);
 
    /* move the head to point
    to the new node */
    (head_ref) = new_node;
    return head_ref;
}
 
/* A utility function to print linked list */
static void printList(Node node)
{
    while (node != null)
    {
        Console.Write(node.data + " -> ");
        node = node.next;
    }
    Console.Write("null");
}
 
// Function that rotates the given linked list
// clockwise by k and returns the updated
// head pointer
static Node rightRotate(Node head, int k)
{
 
    // If the linked list is empty
    if (head == null)
        return head;
 
    // len is used to store length of
    // the linked list, tmp will point
    // to the last node after this loop
    Node tmp = head;
    int len = 1;
    while (tmp.next != null)
    {
        tmp = tmp.next;
        len++;
    }
 
    // If k is greater than the size
    // of the linked list
    if (k > len)
        k = k % len;
 
    // Subtract from length to convert
    // it into left rotation
    k = len - k;
 
    // If no rotation needed then
    // return the head node   
    if (k == 0 || k == len)
        return head;
 
    // current will either point to
    // kth or null after this loop
    Node current = head;
    int cnt = 1;
    while (cnt < k && current != null)
    {
        current = current.next;
        cnt++;
    }
 
    // If current is null then k is equal
    // to the count of nodes in the list
    // Don't change the list in this case
    if (current == null)
        return head;
 
    // current points to the kth node
    Node kthnode = current;
 
    // Change next of last node
    // to previous head
    tmp.next = head;
 
    // Change head to (k+1)th node
    head = kthnode.next;
 
    // Change next of kth node to null
    kthnode.next = null;
 
    // Return the updated head pointer
    return head;
}
 
// Driver code
public static void Main(String []args)
{
 
    /* The constructed linked list is:
    1.2.3.4.5 */
    Node head = null;
    head = push(head, 5);
    head = push(head, 4);
    head = push(head, 3);
    head = push(head, 2);
    head = push(head, 1);
 
    int k = 2;
 
    // Rotate the linked list
    Node updated_head = rightRotate(head, k);
 
    // Print the rotated linked list
    printList(updated_head);
}
}
 
// This code is contributed by PrinciRaj1992


Javascript


C++
#include 
using namespace std;
class Node {
public:
    int val;
    Node* next;
    Node(int d)
    {
        val = d;
        next = NULL;
    }
};
void build(Node*& head, int val)
{
    if (head == NULL) {
        head = new Node(val);
    }
    else {
        Node* temp = head;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        temp->next = new Node(val);
    }
}
Node* rotate_clockwise(Node* head, int k)
{
    if (head == NULL) {
        return NULL;
    }
    deque q;
    Node* temp = head;
    while (temp != NULL) {
        q.push_back(temp);
        temp = temp->next;
    }
    k %= q.size();
    while (
        k--) // popping from back and adding to it's front
    {
        q.back()->next = q.front();
        q.push_front(q.back());
        q.pop_back();
        q.back()->next = NULL;
    }
    return q.front();
}
void print(Node* head)
{
    while (head != NULL) {
        cout << head->val << " -> ";
        head = head->next;
    }
    cout << "NULL";
    cout << endl;
}
int main()
{
    Node* head = NULL;
    build(head, 1);
    build(head, 2);
    build(head, 3);
    build(head, 4);
    build(head, 5);
    int k = 2;
    Node* r = rotate_clockwise(head, k);
    print(r);
    return 0;
}


输出:
4 -> 5 -> 1 -> 2 -> 3 -> NULL

时间复杂度: O(n),其中 n 是链表中的节点数。

基于 STL 的方法:

这个问题也可以使用C++ STL中提供的deque数据结构来解决

方法 :

初始化一个类型为 Node* 的双端队列并将链表推入其中。然后继续从它的后面弹出并将该节点添加到它的前面,直到操作数不等于 k。

C++

#include 
using namespace std;
class Node {
public:
    int val;
    Node* next;
    Node(int d)
    {
        val = d;
        next = NULL;
    }
};
void build(Node*& head, int val)
{
    if (head == NULL) {
        head = new Node(val);
    }
    else {
        Node* temp = head;
        while (temp->next != NULL) {
            temp = temp->next;
        }
        temp->next = new Node(val);
    }
}
Node* rotate_clockwise(Node* head, int k)
{
    if (head == NULL) {
        return NULL;
    }
    deque q;
    Node* temp = head;
    while (temp != NULL) {
        q.push_back(temp);
        temp = temp->next;
    }
    k %= q.size();
    while (
        k--) // popping from back and adding to it's front
    {
        q.back()->next = q.front();
        q.push_front(q.back());
        q.pop_back();
        q.back()->next = NULL;
    }
    return q.front();
}
void print(Node* head)
{
    while (head != NULL) {
        cout << head->val << " -> ";
        head = head->next;
    }
    cout << "NULL";
    cout << endl;
}
int main()
{
    Node* head = NULL;
    build(head, 1);
    build(head, 2);
    build(head, 3);
    build(head, 4);
    build(head, 5);
    int k = 2;
    Node* r = rotate_clockwise(head, k);
    print(r);
    return 0;
}
输出
4 -> 5 -> 1 -> 2 -> 3 -> NULL

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程