0
点赞
收藏
分享

微信扫一扫

单链表学习-反转

逸省 2022-01-20 阅读 66
#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;
}
举报

相关推荐

0 条评论