C++程序 分组反转链表 – 1
给定一个链表,编写一个函数来反转每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
算法: 反转 (head, k)
- 反转第一个大小为k的子列表。反转时跟踪下一个节点和上一个节点。将指向下一个节点的指针设为 next ,将指向上一个节点的指针设为 prev 。请参见这篇文章中的反转链表
- head- >next = reverse(next, k) ( 对线路的其余部分进行递归调用,并将两个子列表链接在一起 )
- 返回 prev ( prev 成为列表的新头(请参见这篇文章的迭代方法的图解)
下面的图像显示了反转函数的工作原理:
下面是上述方法的实现:
// C ++程序反转链表 //按给定大小分组 #include <bits/stdc++.h> using namespace std; //链接列表节点 class Node { public: int data; Node* next; }; /* 反转链表在组中 大小为k,并返回指针 到新的头节点。 */ Node* reverse(Node* head, int k) { // 基本情况 if (!head) return NULL; Node* current = head; Node* next = NULL; Node* prev = NULL; int count = 0; // 反转链表的前k个节点 while (current != NULL && count < k) { next = current->next; current->next = prev; prev = current; current = next; count++; } /* next现在是指向第(k+1)个节点的指针 从当前开始递归调用列表。并使列表的其余部分 作为第一个节点的下一个 */ if (next != NULL) head->next = reverse(next, k); // prev是输入列表的新头 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; /* 创建连接列表 1->2->3->4->5->6->7->8->9 */ 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 << "给定链接列表 "; printList(head); head = reverse(head, 3); cout << "反转链表 "; printList(head); return (0); } //这些代码由rathbhupendra贡献```
输出:
给定链接列表 1 2 3 4 5 6 7 8 9 反转列表 3 2 1 6 5 4 9 8 7
复杂度分析:
- 时间复杂度: O(n)。 只需要对列表进行一次遍历,且列表有n个元素。
- 空间复杂度: O(n/k)。 每个大小为n的链表,在递归过程中需要进行n/k或(n/k)+1次调用。
版权声明:本页面内容旨在传播知识,为用户自行发布,若有侵权等问题请及时与本网联系,我们将第一时间处理。E-mail:284563525@qq.com