/*
1 迭代反转链表
思路:从当前链表的首元节点开始,一直遍历至链表的最后一个节点,这期间会逐个改变所遍历到的节点的指针域,
另其指向前一个节点。
链表 1-->2-->3-->4-->5
逆链表 1<--2<--3<--4<--5
步骤:
第一步:三个节点,前中后节点,前节点指向空,中节点指向头结点head;
第二步:当当前节点不为空时,则后节点指向头结点下一个节点,当前节点指向先前节点pPreNode,当前节点向前移动到先前节点,下一个节点移动到当前节点;
第三步:输出头结点
/
ListNode *ReverseList(ListNode *head)
{
if (pHead == nullptr) {return nullptr;
}
if (pHead->next == nullptr) {
return pHead;
}
ListNode *pPreNode = nullptr;
ListNode *pCurrNode = head;while(pCurrNode != nullptr) {
ListNode *pNextNode = pCurrNode->next; //当前节点下一个节点存储到pNextNode pCurrNode->next = pPreNode; //当前节点指向先前节点pPreNode pPreNode = pCurrNode; // 当前节点向前移动到先前节点 pCurrNode = pNextNode; // 下一个节点移动到当前节点
}
return pPreNode; //反转的头节点
}
/*
2 递归反转链表
思路:和迭代反转法的思想恰好相反,递归反转法的实现思想是从链表的尾节点开始,
依次向前遍历,遍历过程依次改变各节点的指向,即另其指向前一个节点。
步骤:
第一步:从第一个循环递归到倒数第二个节点,通过倒数第二个节点指向最后一个节点,
输出的节点为最后一个节点,作为新的头节点pHeadNode;
第二步:最后一个节点指向倒数第二节点
第三步:倒数第二个指针域为空
/
ListNode *ReverseList(ListNode *head)
{
if (pHead == nullptr) {return nullptr;
}
if (pHead->next == nullptr) {
return pHead;
}
ListNode *pCurrNode = head;
ListNode *pHeadNode = ReverseList(pCurrNode->next); //pCurrNode->next为倒数第二节点
pCurrNode->next->next = pCurrNode; //最后一个节点指向倒数第二个节点
pCurrNode->next = nullptr; //倒数第二个节点指向空return pHeadNode; //反转的头节点
}
/*
3 头插法反转链表
思路:指在原有链表的基础上,依次将位于链表头部的节点摘下,然后采用从
头部插入的方式生成一个新链表,则此链表即为原链表的反转版。
步骤:
第一步:创建一个新节点,目的创建一个新链表
第二步:保存头节点,即断开头节点,移到下一个节点
第三步:保存头节点指向一个空节点,移到下一个节点
第四步:循环
/
ListNode ReverseList(ListNode *head)
{
if (pHead == nullptr) {return nullptr;
}
if (pHead->next == nullptr) {
return pHead;
}
ListNode *newHeadNode = nullptr;
ListNode *tempNode = nullptr;
while (head != nullptr) {tempNode = head; // 保存头节点,即断开头节点 head = head->next; //移到下一个节点 tempNode->next = newHeadNode; //保存头节点指向一个空节点 newHeadNode = tempNode; //新节点,移到下一个节点
}
return newHeadNode;
}
/*
- 4 就地逆置反转法
- 与头插法的区别:就地逆置法和头插法的实现思想类似,唯一的区别在于,头插法是通过建立一个新链表实现的,
- 而就地逆置法则是直接对原链表做修改,从而实现将原链表反转。
- 思想:从第二个节点开始到最后一个节点,依次取出来,第二个节点重新链接第一个节点,第三个节点链接第二个节点,...,第n个
- 节点链接第n-1个节点。
- 步骤:
- 第一步:选择2个节点,一个为前节点pPreNode,另一个为后节点pEndNode;
- 第二步:当后节点不为空,则前节点pPreNode(第一个节点)链接后节点pEndNode的下一个节点(第三个节点),即断开第二个节点;
- pEndNode(第二个节点)链接头节点head;pEndNode节点向head节点移动;pPreNode节点向pEndNode移位。依次循环...
- 第三步: 输出头节点head
- /
ListNode ReverseList(ListNode *head)
{
if (pHead == nullptr) {
return nullptr;
}
if (pHead->next == nullptr) { return pHead; } ListNode *pPreNode = head; ListNode *pEndNode = head->next; while (pEndNode != nullptr) { pPreNode->next = pEndNode->next; //断开了第二个节点,第一个节点与第三个节点链接 pEndNode->next = head; // 第二个节点链接第一个节点 head = pEndNode; // 向下移位 pEndNode = pPreNode->next; //向下移位 } return head;
}