#include<iostream>
using namespace std;
//定义一个链表结构体
struct ListNode
{
int val;
ListNode* next;
ListNode(int x) :val(x), next(NULL) {}
};
//尾插法链表
ListNode* ListCreate(int n)
{
//创建虚拟头结点head
ListNode* head = new ListNode(-1);
//创建尾指针指向头结点
ListNode* tail = head;
//通过循环不断将新节点添加到链表尾部
for (int i = 1; i <= n; i++)
{
ListNode* node = new ListNode(i);
tail->next = node;
tail = tail->next;
}
return head->next;
}
/*
链表的部分逆置
1.先找到需要逆置的节点区间
2.将区间内的节点按照逆序进行重新连接
reverseBetween:逆置函数
参数:
head:头节点
m和n为逆置区间
返回值:
ListNode*
*/
ListNode* reverseBetween(ListNode* head, int m, int n)
{
/*
1.特殊情况判断:链表为空、链表只有一个节点或者m与n相等
无需进行逆置则返回原链表
*/
if (head == NULL || head->next == NULL || m == n)
{
return head;
}
//创建虚拟头节点dummy,并将其指向链表头节点。
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode* prev = dummy;
//使用for循环将prev指针移动到第m-1个节点位置
for (int i = 1; i < m; i++)
{
prev = prev->next;
}
//将curr指针指向第m个节点位置
ListNode* curr = prev->next;
//将next指针指向第m+1个节点位置,这样我们找到了需要逆置节点的区间
ListNode* next = curr->next;
/*
假设要将区间[2,3]逆置:
m-1 m m+1
1 -> 2 -> 3 -> 4 -> 5 -> NULL
prev curr next
*/
//接下来我们使用for循环将节点逆序。
for (int i = 0; i < n - m; i++)
{
//curr节点的next域指向next节点的下一个节点,即 2->4
curr->next = next->next;
//next节点的next域指向prev的下一个节点,即 3->2
next->next = prev->next;
//最后将next节点插入到prev节点后,即1->3
prev->next = next;
//由于next节点已近插入到prev节点后面,因此需要将next移动到下一个节点以便下一次循环,这里没变。
/*
m-1 m m+1
1 -> 3 -> 2 -> 4 -> 5 -> NULL
prev curr next
*/
next = curr->next;
}
return dummy->next;
}
void printList(ListNode* head)
{
ListNode* temp = head;
while (temp != NULL)
{
cout << temp->val << "->";
temp = temp->next;
}
cout << "NULL" << endl;
}
int main()
{
ListNode* head = ListCreate(5);
cout << "逆置前:" << endl;
printList(head);
cout << "部分逆置后:" << endl;
head = reverseBetween(head, 2, 3);
printList(head);
system("pause");
return 0;
}