小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
给定一个链表,编写一个函数来反转每 k 个节点(其中 k 是函数的输入)。
例子:
输入:1->2->3->4->5->6->7->8->NULL,K = 3
输出:3->2->1->6->5->4- >8->7->NULL
输入:1->2->3->4->5->6->7->8->NULL,K = 5
输出:5->4->3-> 2->1->8->7->6->NULL
算法:反向 (头,k)
- 反转大小为 k 的第一个子列表。倒车时跟踪下一个节点和上一个节点。让指向下一个节点的指针为next,指向前一个节点的指针为prev。请参阅此帖子以反转链接列表。
- head->next = reverse(next, k) (递归调用列表的其余部分并链接两个子列表)
- 返回prev(prev成为列表的新头(参见这篇文章的迭代方法图)
下面是上述方法的实现:
#include <bits/stdc++.h>
using namespace std;
class Node {
public:
int data;
Node* next;
};
Node* reverse(Node* head, int k)
{
if (!head)
return NULL;
Node* current = head;
Node* next = NULL;
Node* prev = NULL;
int count = 0;
while (current != NULL && count < k) {
next = current->next;
current->next = prev;
prev = current;
current = next;
count++;
}
if (next != NULL)
head->next = reverse(next, k);
return prev;
}
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;
push(&head, 9);
push(&head, 8);
push(&head, 7);
push(&head, 6);
push(&head, 5);
push(&head, 4);
push(&head, 3);
push(&head, 2);
push(&head, 1);
cout << "Given linked list \n";
printList(head);
head = reverse(head, 3);
cout << "\nReversed Linked list \n";
printList(head);
return (0);
}
输出:
Given Linked List
1 2 3 4 5 6 7 8 9
Reversed list
3 2 1 6 5 4 9 8 7
复杂度分析:
-
时间复杂度: O(n)。
列表的遍历只完成一次,它有 'n' 个元素。 -
辅助空间: O(n/k)。
对于每个大小为 n 的链表,将在递归期间进行 n/k 或 (n/k)+1 调用。🥇 往期优质文章
数据结构单链表之链表介绍 | 第一套
数据结构单链表之链表与数组 | 第二套
数据结构单链表之链表插入 | 第三套
数据结构单链表之删除节点 | 第四套
数据结构单链表之删除给定位置的链表节点 | 第五套
数据结构单链表之查看数组与链表的方法 | 第六套-1
数据结构单链表之查看数组与链表的方法 | 第六套-2
数据结构单链表之查找链表的长度(迭代和递归) | 第七套
数据结构单链表之交换链表中的节点而不交换数据 | 第八套
数据结构单链表之反转链表 | 第九套
数据结构单链表之合并两个已排序的链表 | 第十套
数据结构单链表之链表的归并排序 | 第十一套
📣尾注: 想要获取更多数据结构相关的知识,你可以关注我:海拥,我希望你觉得这篇文章有帮助。
如果你看到这里,感谢你的阅读 :)
💌 欢迎大家在评论区提出意见和建议!💌
如果你真的从这篇文章中学到了一些新东西,喜欢它,收藏它并与你的小伙伴分享。🤗最后,不要忘了❤或📑支持一下哦。