📜  C程序以块方式旋转链表(1)

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

C程序以块方式旋转链表

在本文中,我们将介绍如何使用块方式旋转链表的C程序。

什么是块方式旋转链表?

块方式旋转链表是一种将链表的节点旋转一定数量的方法。具体来说,它将原始链表拆分成“块”,并对每个块的节点进行旋转。通过这种方式,我们可以快速、高效地旋转大型链表。

如何实现块方式旋转链表?

下面是一个基本的C程序,它演示了如何使用块方式旋转链表。

#include <stdio.h>
#include <stdlib.h>

/* 定义链表节点结构体 */
typedef struct node {
    int data;
    struct node* next;
} node_t;

/* 创建新节点 */
node_t* create_node(int data) {
    node_t* new_node = (node_t*)malloc(sizeof(node_t));
    new_node->data = data;
    new_node->next = NULL;
    return new_node;
}

/* 输出链表 */
void print_list(node_t* head) {
    while (head != NULL) {
        printf("%d -> ", head->data);
        head = head->next;
    }
    printf("NULL\n");
}

/* 块方式旋转链表 */
node_t* rotate_list(node_t* head, int k) {
    /* 边界情况 */
    if (head == NULL || head->next == NULL || k == 0) {
        return head;
    }
    
    /* 计算链表长度 */
    int len = 1;
    node_t* tail = head;
    while (tail->next != NULL) {
        len++;
        tail = tail->next;
    }
    
    /* 因为旋转后,第k个节点变为新的表头节点,
       因此将原表头节点指向第k+1个节点,
       将第k个节点指向新的表头节点(tail->next指向原表头节点) */
    k %= len;
    if (k == 0) {
        return head;
    }
    tail->next = head;
    for (int i = 0; i < len - k; i++) {
        tail = tail->next;
    }
    head = tail->next;
    tail->next = NULL;
    
    return head;
}

/* 测试块方式旋转链表 */
int main(void) {
    node_t* head = create_node(1);
    node_t* node2 = create_node(2);
    node_t* node3 = create_node(3);
    node_t* node4 = create_node(4);
    node_t* node5 = create_node(5);
    
    head->next = node2;
    node2->next = node3;
    node3->next = node4;
    node4->next = node5;
    
    printf("原始链表:");
    print_list(head);
    
    int k = 2;
    node_t* new_head = rotate_list(head, k);
    
    printf("旋转 k = %d 后的链表:", k);
    print_list(new_head);
    
    return 0;
}

这个程序使用create_node()函数创建链表节点。print_list()函数用于将链表打印出来,以检查我们的旋转方式是否正确。rotate_list()函数是我们的核心函数。它使用两个指针tail和head来表示链表的头和尾节点。首先,我们计算链表的长度。根据“k mod length”的计算结果,我们找到新表头节点。然后我们将链表从原始链表切断,将尾指针tail指向新的表头节点,将头指针head指向tail->next(原始表头节点)。最后,我们将tail->next置为NULL,以确保我们的新链表正确连接。