C++程序 按块旋转链表

C++程序 按块旋转链表

给定长度为n的链表和块长度 k ,通过一个数字 d ,以环形方式向右/向左旋转每个块。如果 d 为正数,则向右旋转,否则向左旋转。

示例:

输入: 1->2->3->4->5->6->7->8->9->NULL,
k = 3
d = 1
输出: 3->1->2->6->4->5->9->7->8->NULL
解释: 这里块的大小为3,朝右旋转(因为d是正数)1次。

输入: 1->2->3->4->5->6->7->8->9->10->
11->12->13->14->15->NULL,
k = 4
d = -1
输出: 2->3->4->1->6->7->8->5->10->11->
12->9->14->15->13->NULL
解释: 在链表的末尾,剩余的节点少于k,即在k为4时仅剩3个节点。同样需要根据d将这三个节点旋转。

这个想法是,如果d的绝对值大于k的值,则将链表旋转d % k次。如果d为0,则根本不需要旋转链表。

// C++程序用于块旋转链接列表
//block wise 
#include<bits/stdc++.h>
using namespace std;
  
//链接列表节点
class Node 
{ 
    public:
    int data; 
    Node* next; 
}; 
  
//递归函数以旋转
//一个块
Node* rotateHelper(Node* blockHead, 
                   Node* blockTail, 
                   int d, Node** tail, 
                   int k) 
{ 
    if (d == 0) 
        return blockHead; 
  
    //顺时针旋转
    if (d > 0) 
    { 
        Node* temp = blockHead; 
        for (int i = 1; temp->next->next && 
                 i < k - 1; i++) 
            temp = temp->next; 
  
        blockTail->next = blockHead; 
        *tail = temp; 
        return rotateHelper(blockTail, temp, 
                            d - 1, tail, k); 
    } 
  
    //逆时针旋转
    if (d < 0) 
    { 
        blockTail->next = blockHead; 
        *tail = blockHead; 
        return rotateHelper(blockHead->next, 
                            blockHead, d + 1, 
                            tail, k); 
    } 
} 
  
//函数以块方式旋转链接列表
Node* rotateByBlocks(Node* head, 
                     int k, int d) 
{ 
    //如果长度为0或1,则返回头部 
    if (!head || !head->next) 
        return head; 
  
    //如果旋转度为0,则返回头部 
    if (d == 0) 
        return head; 
  
    Node* temp = head, *tail = NULL; 
  
    //遍历直到该块的最后一个元素 
    int i; 
    for (i = 1; temp->next && i < k; i++) 
         temp = temp->next; 
  
    //存储下一个块的第一个节点
    Node* nextBlock = temp->next; 
  
    //如果该块的节点少于k,则也旋转该块
    if (i < k) 
        head = rotateHelper(head, temp, 
                            d % k, &tail, i); 
    else
        head = rotateHelper(head, temp, 
                            d % k, &tail, k); 
  
    //将下一个块的新头部追加到该块的尾部
    tail->next = rotateByBlocks(nextBlock, 
                                k, d % k); 
  
    //返回更新后的链接列表的头部
    return head; 
} 
  
//实用函数
//将节点压入链表
void push(Node** head_ref, 
          int new_data) 
{ 
    Node* new_node = new Node; 
    new_node->data = new_data; 
    new_node->next = (*head_ref); 
    (*head_ref) = new_node; 
} 
  
//打印链接列表的函数
void printList(Node* node) 
{ 
    while (node != NULL) 
    { 
        cout << node->data << " "; 
        node = node->next; 
    } 
} 
  
// 驱动程序
int main() 
{ 
    //从空列表开始
    Node* head = NULL; 
  
    //创建一个列表 1->2->3->4->5->6->7->8->9->NULL 
    for (int i = 9; i > 0; i -= 1) 
        push(&head, i); 
  
    cout << 
    "Given linked list "; 
    printList(head); 
  
    // k是块大小,d是每个块中旋转的次数。
    int k = 3, d = 2; 
    head = rotateByBlocks(head, k, d); 
  
    cout <<
    "Rotated by blocks Linked list "; 
    printList(head); 
  
    return (0); 
} 

输出:

给定的链接列表
1 2 3 4 5 6 7 8 9
以块旋转的链接列表
2 3 1 5 6 4 8 9 7

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

C++ 示例