#include <iostream>
using namespace std;
class LinkedList{
public:
int val;
LinkedList *next;
LinkedList(int _val): val(_val), next(NULL){}
};
// 递归逆序打印单链表
void rtraverse(LinkedList *head) {
if(!head)
return;
rtraverse(head->next);
cout << head->val << " ";
}
// 递归正序打印单链表
void traverse(LinkedList *head) {
if(!head)
return;
cout << head->val << " ";
traverse(head->next);
}
// 递归反转整个链表
// 以 1->(2) 2->(3) 3->(4) 4->(NULL)为例
// 4->(NULL)的环境下,直接返回 4->(NULL) 并设置新的head为new_head
// 在 3->(4) 的环境下,对拿到的 4->(NULL),重新更改为 3->(NULL) 4->(3) ,返回 3->(NULL)
// 在 2->(3) 的环境下,对拿到的 3->(NULL) 4->(3) ,重新更改为 2->(NULL) 3->(2) 4->(3),返回 2->(NULL)
// 在 1->(2) 的环境下,对拿到的 2->(NULL) 3->(2) 4->(3) ,重新更改为 1->(NULL) 2->(1) 3->(2) 4->(3),返回 1->(NULL)
LinkedList* reverseLinkedList(LinkedList *head, LinkedList **new_head){
if (!head->next) {
*new_head = head;
return head;
}
LinkedList *last = reverseLinkedList(head->next, new_head);
head->next->next = head;
head->next = NULL;
return head;
}
// 反转链表前N个节点
// 1->(2) 2->(3) 3->(4) 4->(NULL) 反转前3个节点
// 变成
// 1->(4) 2->(1) 3->(2) 4->(NULL)
// 递归进去后,肯定要找到新的头部 3->() 和 后继节点 4->(NULL)
// 因为最终要填充新的头部,以及将 后继节点补到第一个节点的next上
// 1->(2) 2->(3) 3->(4) 4->(NULL) 分析:
// head 3->(4) 的环境下,n=1,找到了新头部 new_head 为 3->(4) 找到了后继 successor = 4->(NULL),返回 3->(4)
// head 2->(3) 的环境下,n=2,last = 3->(4),此时改为:2->(NULL) 3->(2) 返回 2->(NULL)
// head 1->(2) 的环境下,n=3,last = 2->(NULL) 3->(2),此时改为:1->(NULL), 2->(1) 3->(2) 返回 1->(NULL)
LinkedList* reversePartialLinkedListHelper(LinkedList *head, LinkedList **new_head, int n, LinkedList **successor){
if (n == 1) {
*successor = head->next;
*new_head = head;
return head;
}
LinkedList *last = reversePartialLinkedListHelper(head->next, new_head, n-1, successor);
head->next->next = head;
head->next = NULL;
return head;
}
LinkedList* reversePartialLinkedList(LinkedList *head, int n) {
if (n <= 1) return head;
LinkedList *new_head;
LinkedList *successor;
LinkedList *old_head;
old_head = reversePartialLinkedListHelper(head, &new_head, n, &successor);
old_head->next = successor;
return new_head;
}
// 返回 m-n之间反转,其他正序的节点
// 1->(2) 2->(3) 3->(4) 4->(5) 5->(NULL) m = 2 n = 4
// head = 1->(2) 2->(3) 3->(4) 4->(5) 5->(NULL) m = 2 n = 4
// head->next = {
// head = 2->(3) 3->(4) 4->(5) 5->(NULL) m = 1 n = 3
// return reversePartialLinkedList(2, 3);
// 4->(3) 3->(2) 2->(5) 5->(NULL)
// }
// 1->(4)
// 最后变成 1->(4) 4->(3) 3->(2) 2->(5) 5->(NULL)
LinkedList* reverseRangeLinkedList(LinkedList *head, int m, int n) {
if (!head || !head->next || m >= n || m <= 0 || n <= 0)
return head;
if (m == 1) {
return reversePartialLinkedList(head, n);
}
head->next = reverseRangeLinkedList(head->next, m-1, n-1);
return head;
}
int main()
{
LinkedList *l1 = new LinkedList(1);
LinkedList *l2 = new LinkedList(2);
LinkedList *l3 = new LinkedList(3);
LinkedList *l4 = new LinkedList(4);
LinkedList *l5 = new LinkedList(5);
l1->next = l2;
l2->next = l3;
l3->next = l4;
l4->next = l5;
// traverse(l1);
// cout<<endl;
// rtraverse(l1);
// cout<<endl;
traverse(reverseRangeLinkedList(l1, 2, 4));
delete l1;
delete l2;
delete l3;
delete l4;
return 0;
}