反转链表
定义一个函数,输入一个链表的头节点,反转该链表并输出反转后链表的头节点。
输入: 1->2->3->4->5->NULL
输出: 5->4->3->2->1->NULL
共有三种方法,
第一种,双指针法,设置俩个指针,cur,pre,先让cur指向空,pre指向头指针,然后每一次循环让pre的next指向cur,将cur,pre向前移动一位。
下面展示一些 内联代码片
。
ListNode* reverseList(ListNode* head) {
ListNode* cur = NULL, *pre = head;//cur指向空,pre指向该节点
while (pre != NULL) {
ListNode* t = pre->next;//记录pre的next指向
pre->next = cur;//让pre的next指向cur
cur = pre;//将cur往前移动一位
pre = t;//将pre往前移动一位
}
return cur;
}//例如,该链表为1,2,3,
//我们先将cur指向空,pre指向1,pre->next为1,然后第一场循环,pre->next指向空,cur指向1,pre指向2,第一次循环结束。第二次循环,pre->next指向1,即2的下一个指向1,然后cur指向2,pre指向3。。。。。
第二个方法,递归法。
该方法是先一直递归到最后一个元素,返回自己的地址,以便于记下反转后的头结点,然后从倒数第二个开始,让他的下一个结点的next指向自己,然后让自己的next指向空,一直递归回到输入的头结点
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL) {//如果头结点为空或者该结点为反转后的头结点,返回该结点的地址
return head;
}
ListNode* ret = reverseList(head->next);//先递归,一直递归到最后一个结点。
head->next->next = head;//该结点的下一个结点的next指向自己
head->next = NULL;//该结点的next指向空
return ret;//返回ret,即返回反转后的头结点。
}
例如,1,2,3。代码步骤:先递归到3,3的next为空,则返回head即自己的地址,if语句下面的代码不执行,然后回到结点2,因为2的next不为空,执行下面的代码,ret为下一次递归的返回值,即3的返回值,3的地址,即反转后的头结点,然后2的下一个结点即3的next被赋值为2,即3的next指向2,2的next指向空,返回3的地址。然后执行1的递归下面的代码,1的next为2,2的next指向1,1的next指向空,返回3的地址,结束。
第三个方法是双指针法,
`
该方法和递归类似,就是让cur每次都等于下一个结点的next,例如1,2,3,4,先让cur为1,让2指向1,然后head->next向前一步变为3,cur变为2,在让3指向2,如此循环
ListNode* reverseList(ListNode* head) {
if (head == NULL) { return NULL; }
ListNode* cur = head;
while (head->next != NULL) {
ListNode* t = head->next->next;//将该结点的next的next记录下来,以便让一次循环结束后能让该结点的next向前一步。
head->next->next = cur;//将该结点的next的next指向该结点,
cur = head->next;//将cur向前一步
head->next = t;//将head->next向前一步
}
return cur;
}
该题出自力扣,反转思路来自题解,网站如下
https://leetcode-cn.com/problems/fan-zhuan-lian-biao-lcof/solution/fan-zhuan-lian-biao-yi-dong-de-shuang-zhi-zhen-jia/