归并排序----单向链表
1:单向链表快速寻找中间结点
快慢指针:慢指针走一步,快指针走两步
// 精彩代码--快慢指针寻找列表 中点
// 快慢指针寻找列表 的中点
ListNode* findMid(ListNode* head, ListNode* tail) { // [head, tail); tail == nullptr
ListNode* fast;
ListNode* slow;
slow = head;
fast = head->next;
if (fast->next == nullptr) {
return slow;
}
while (fast != tail) {
slow = slow->next;
fast = fast->next;
if (fast != tail) {
fast = fast->next;
}
}
return slow;
}
2:哨兵结点的引入
指向第一个结点,方便将结点插入到头节点的前面
ListNode* merge(ListNode* head1, ListNode* head2) {
// head2 --> head1 中
// 一个形式头结点
// 在 head1 所指向的 链表之前创建出一个 形式头节点
// 为了以后插入元素方便
ListNode* hot = new ListNode(-1);
hot->next = head1;
ListNode* ptr1 = head1;
ListNode* ptr2 = head2;
ListNode* tmp = hot; // hot 出现的很少,但很关键
// 短的链表插入到长的链表中去
while (ptr1 != nullptr && ptr2 != nullptr) {
if (ptr1->val <= ptr2->val) {
tmp = tmp->next; // 空结点的前一个结点
ptr1 = ptr1->next;
} else {
tmp = insert_one(tmp, ptr2->val);
ptr2 = ptr2->next;
}
}
// 第二条链表中还有元素没有插入完的话
while (ptr2 != nullptr) {
tmp = insert_one(tmp, ptr2->val);
ptr2 = ptr2->next;
}
return hot->next;
}
归并排序—单向链表排序 完整版代码
#include <iostream>
using namespace std;
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) {}
};
class Solution {
public:
// 快慢指针寻找列表 的中点
ListNode* findMid(ListNode* head, ListNode* tail) { // [head, tail); tail == nullptr
ListNode* fast;
ListNode* slow;
slow = head;
fast = head->next;
if (fast->next == nullptr) {
return slow;
}
while (fast != tail) {
slow = slow->next;
fast = fast->next;
if (fast != tail) {
fast = fast->next;
}
}
return slow;
}
// 插入到 head1 的后面
ListNode* insert_one(ListNode* head1, int val) {
if (head1 == nullptr) {
return nullptr;
}
ListNode* tmp = nullptr;
tmp = new ListNode(val);
tmp->next = head1->next;
head1->next = tmp;
return tmp; // 返回指向新结点的指针
}
// 合并有序单链表
// head1 可以和空 链表合并, head1 || head2 为空,merge 都能很好的完成工作
ListNode* merge(ListNode* head1, ListNode* head2) {
// head2 --> head1 中
// 一个形式头结点
// 在 head1 所指向的 链表之前创建出一个 形式头节点
// 为了以后插入元素方便
ListNode* hot = new ListNode(-1);
hot->next = head1;
ListNode* ptr1 = head1;
ListNode* ptr2 = head2;
ListNode* tmp = hot; // hot 出现的很少,但很关键
// 短的链表插入到长的链表中去
while (ptr1 != nullptr && ptr2 != nullptr) {
if (ptr1->val <= ptr2->val) {
tmp = tmp->next; // 空结点的前一个结点
ptr1 = ptr1->next;
} else {
tmp = insert_one(tmp, ptr2->val);
ptr2 = ptr2->next;
}
}
// 第二条链表中还有元素没有插入完的话
while (ptr2 != nullptr) {
tmp = insert_one(tmp, ptr2->val);
ptr2 = ptr2->next;
}
return hot->next;
}
void mergeSort(ListNode* &head, ListNode* tail) {
if (head == nullptr || head->next == nullptr) {
return;
}
ListNode* tmp = findMid(head, tail);
ListNode* tmp2 = tmp->next;
tmp->next = nullptr;
mergeSort(head, tmp->next); // [head, ]
mergeSort(tmp2, tail); // [tmp2, tail)
head = merge(head, tmp2);
}
ListNode* sortList(ListNode* head) {
if (head == nullptr) {
return head;
}
mergeSort(head, nullptr);
return head;
}
void display(ListNode* ptr) {
while (ptr != nullptr) {
cout << ptr->val << " ";
ptr = ptr->next;
}
cout << endl;
}
};
int main() {
Solution lt;
ListNode n1(5);
ListNode n2(2);
//ListNode n3(1);
n1.next = &n2;
//n2.next = &n3;
//n3.next = &n4;
lt.display(lt.sortList(&n1));
return 0;
}