C++ 程序 将链表中从位置 M 到位置 N 的子列表向右旋转 K 次
简介
在程序开发中,我们经常需要对链表进行各种操作。今天,我们来介绍一种 C++ 程序,可以将链表中从位置 M 到位置 N 的子列表向右旋转 K 次。
算法
我们可以使用双指针来完成这个算法。首先,我们需要判断输入参数的合法性,然后找到需要旋转的子链表的头节点和尾节点。接着,我们对要旋转的节点进行计算,得到需要向右旋转的次数,并计算出需要调整的节点数量。最后,我们进行节点的旋转操作即可。
下面是示例代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseBetween(ListNode* head, int m, int n, int k) {
if (head == NULL || m >= n || k <= 0) { // 判断输入参数的合法性
return head;
}
// 找到需要旋转的子链表的头节点和尾节点
ListNode *start = head;
ListNode *end = head;
ListNode *prev_start = NULL;
ListNode *next_end = NULL;
for (int i = 1; i < m; ++i) {
prev_start = start;
start = start->next;
}
for (int i = 1; i <= n; ++i) {
end = end->next;
}
next_end = end->next;
// 计算需要向右旋转的次数
int len = n - m + 1;
k = k % len;
if (k == 0) { // 不需要旋转,直接返回原链表
return head;
}
// 计算需要调整的节点数量
int num = len - k;
// 双指针寻找需要调整的节点
ListNode *p = start;
ListNode *q = start->next;
for (int i = 1; i < num; ++i) {
ListNode *r = q->next;
q->next = p;
p = q;
q = r;
}
// 连接链表
if (prev_start != NULL) {
prev_start->next = p;
}
start->next = next_end;
return head;
}
};
示例
假设我们已经有一个链表 1->2->3->4->5,我们要将位置 2 到位置 4 的子链表向右旋转 2 次,我们可以使用上面的算法来实现。下面是示例代码:
ListNode *head = new ListNode(1);
head->next = new ListNode(2);
head->next->next = new ListNode(3);
head->next->next->next = new ListNode(4);
head->next->next->next->next = new ListNode(5);
Solution solution;
ListNode *result = solution.reverseBetween(head, 2, 4, 2);
while (result != NULL) {
cout << result->val << " ";
result = result->next;
}
输出结果为:
1 4 3 2 5
结论
本文介绍了一种 C++ 程序,可以将链表中从位置 M 到位置 N 的子列表向右旋转 K 次。该算法使用双指针的方式,能够高效地完成链表的旋转操作。如果您有任何疑问或建议,请随时与我们联系。