📜  C++程序将链表的子列表从位置M到N向右旋转K位

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

C++程序将链表的子列表从位置M到N向右旋转K位

给定一个链表和两个位置“m”和“n”。任务是将子列表从位置 m 旋转到 n,向右旋转 k 个位置。

例子:

方法:为了旋转从 m 到 n 元素的给定子列表,将列表从第 (n-k+1)节点移动到第 n节点到子列表的开头以完成旋转。
如果 k 大于子列表的大小,那么我们将取其与子列表大小的模数。因此,使用指针和计数器遍历列表,我们将保存第 (m-1)节点,然后使其指向第 (n-k+1)节点,从而将第 (n-k+1)节点带到子列表的开始(前)。
同样,我们将保存第 m节点,然后让第 n节点指向它。为了保持列表的其余部分完好无损,我们将使第 (nk)节点指向 n 的下一个节点(可能为 NULL)。最后我们将得到 k 次右旋子列表。

下面是上述方法的实现:

C++
// C++ implementation of the above approach
#include 
using namespace std;
  
// Definition of node of linkedlist
struct ListNode {
    int data;
    struct ListNode* next;
};
  
// This function take head pointer of list, start and
// end points of sublist that is to be rotated and the
// number k and rotate the sublist to right by k places.
void rotateSubList(ListNode* A, int m, int n, int k)
{
    int size = n - m + 1;
  
    // If k is greater than size of sublist then 
    // we will take its modulo with size of sublist
    if (k > size) {
        k = k % size;
    }
  
    // If k is zero or k is equal to size or k is
    // a multiple of size of sublist then list 
    // remains intact
    if (k == 0 || k == size) {
        ListNode* head = A;
        while (head != NULL) {
            cout << head->data;
            head = head->next;
        }
        return;
    }
  
    ListNode* link = NULL;  // m-th node
    if (m == 1) {
        link = A;
    }
  
    // This loop will traverse all node till
    // end node of sublist.    
    ListNode* c = A;  // Current traversed node
    int count = 0;  // Count of traversed nodes
    ListNode* end = NULL;  
    ListNode* pre = NULL; // Previous of m-th node
    while (c != NULL) {
        count++;
  
        // We will save (m-1)th node and later
        // make it point to (n-k+1)th node
        if (count == m - 1) {
            pre = c;
            link = c->next;
        }
        if (count == n - k) {
            if (m == 1) {
                end = c;
                A = c->next;
            }
            else {
                end = c;
  
                // That is how we bring (n-k+1)th
                // node to front of sublist.
                pre->next = c->next;
            }
        }
  
        // This keeps rest part of list intact.
        if (count == n) {
            ListNode* d = c->next;
            c->next = link;
            end->next = d;
            ListNode* head = A;
            while (head != NULL) {
                cout << head->data << " ";
                head = head->next;
            }
            return;
        }
        c = c->next;
    }
}
  
// Function for creating and linking new nodes
void push(struct ListNode** head, int val)
{
    struct ListNode* new_node = new ListNode;
    new_node->data = val;
    new_node->next = (*head);
    (*head) = new_node;
}
  
// Driver code
int main()
{
    struct ListNode* head = NULL;
    push(&head, 70);
    push(&head, 60);
    push(&head, 50);
    push(&head, 40);
    push(&head, 30);
    push(&head, 20);
    push(&head, 10);
    ListNode* tmp = head;
    cout << "Given List: ";
    while (tmp != NULL) {
        cout << tmp->data << " ";
        tmp = tmp->next;
    }
    cout << endl;
  
    int m = 3, n = 6, k = 2;
    cout << "After rotation of sublist: ";
    rotateSubList(head, m, n, k);
  
    return 0;
}


输出:
Given List: 10 20 30 40 50 60 70 
After rotation of sublist: 10 20 50 60 30 40 70

详情请参阅完整文章将链表的子列表从位置 M 向右旋转 K 位!