- C++ 实现
// -*- coding: utf-8 -*-
// @ Date : 2021/5/20 13:14
// @ Author : RichardLau_Cx
// @ file : Richard.cpp
// @ IDE : Dex-C++
// @ Source : leetcode
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
#include <cstdio>
#include <iostream>
using namespace std;
class Solution {
/**
* Implementation:
* 1. 找中点:快慢指针法(p一次移动一位、q一次移动两位);
* 2. 半反转:将1.过后p指针指向的后一个元素,开始整体反转;
* 3. 合并.
*/
public: // 表明以下的成员变量和成员函数为公有成员,在程序中可以任意调用。
ListNode *reverseList(ListNode *p) {
/**
* 传入值跟返回值皆是指针类型(且是头结点)
* 进行反转链表操作
*/
ListNode *q = p->next; // q指向p指向结点的下一个结点
p->next = nullptr; // 置空
while (q != nullptr) {
// 后面元素不为空,就一直向后移动
ListNode *t = q->next; // 定义临时指针,保存q的下一个元素
q->next = p;
// 赋值向后移动
p = q;
q = t;
}
return p; // 新链表的尾结点
}
void reorderList(ListNode* head) { // 刚好传入链表的头结点作为参数
/**
* 给出的函数不需要改任何东西,它会自行根据head去看是否成功反转
*/
// 先特判
if (head == nullptr || head->next == nullptr) {
// 如果头结点为空,或者只有一个元素(头结点下一个为空)
return;
}
// 建立两个指针,均指向头结点
ListNode *p = head, *q = head;
while (q->next != nullptr && q->next->next != nullptr) {
// 1. 找中点(中间结点)
// 不为空,就向后移动
// TODO: 若写成while (p->next != nullptr && q->next->next != nullptr),将偶尔报错(未知原因)
p = p->next;
q = q->next->next;
}
// 2. 半反转
q = reverseList(p->next); // 废物利用,返回从p指针指向的下一个结点开始的反转链表
// 3. 合并两个链表(考试中写得稍细一些)
p->next = nullptr;
p = head;
while (p != nullptr && q != nullptr) {
ListNode *pn = p->next, *qn = q->next; // 新指针分别指向下一个结点
p->next = q;
q->next = pn;
p = pn;
q = qn;
}
// printf(next);
}
};