链表排序
排序这篇是数组排序,刷leetcode的时候碰到了链表排序,记录一下。
插入排序
class Solution {
public:
ListNode* insertionSortList(ListNode* head) {
if(!head) return nullptr;
ListNode* dummy = new ListNode(0);
while(head){
ListNode* p = dummy;//每次重新定义p,相当于每次都是从头遍历
while(p->next && p->next->val <= head->val) p = p->next;
//此时p->next > head->val, p及前面的链表都小于head, head插在此处
ListNode* tmp = head->next;
head->next = p->next;
p->next = head;
head = tmp;//head后移一位,相当于i++
}
ListNode* ans = dummy->next;
delete dummy;
return ans;
}
};
归并排序
// 迭代
class Solution {
public:
ListNode* sortList(ListNode* head) {
// get length of list
int n = 0;
ListNode* p = head;
while (p) {
p = p->next;
n++;
}
ListNode dummy(0);
dummy.next = head;
// each time merge 2 -> 4 -> 8
for (int i = 1; i < n; i *= 2) {
// traverse all list
auto cur = dummy.next;
auto pre = &dummy;
while (cur) {
auto left = cur;
// left->..., right->...
auto right = cut(left, i);
// right->..., cur->...
cur = cut(right, i);
// merge
auto [begin, end] = merge(left, right);
pre->next = begin;
pre = end;
}
}
return dummy.next;
}
// return tail->next
ListNode* cut(ListNode* head, int length) {
while (head && --length) {
head = head->next;
}
if (!head) return nullptr;
auto tmp = head->next;
head->next = nullptr;
return tmp;
}
tuple<ListNode*, ListNode*> merge(ListNode* a, ListNode* b) {
ListNode dummy(0);
ListNode* p = &dummy;
while (a && b) {
if (a->val <= b->val) {
p->next = a;
a = a->next;
}
else {
p->next = b;
b = b->next;
}
p = p->next;
}
while (a) {
p->next = a;
a = a->next;
p = p->next;
}
while (b) {
p->next = b;
b = b->next;
p = p->next;
}
return {dummy.next, p};
}
};
// 递归
class Solution {
public:
ListNode* sortList(ListNode* head) {
return mergeSort(head);
}
ListNode* mergeSort(ListNode* head) {
if (!head || !head->next) return head;
ListNode* slow = head;
ListNode* fast = head;
while (fast->next && fast->next->next) {
slow = slow->next;
fast = fast->next->next;
}
// 此时slow为分割点
ListNode* newHead = slow->next;
slow->next = nullptr;
ListNode* a = mergeSort(head);
ListNode* b = mergeSort(newHead);
return merge(a, b);
}
ListNode* merge(ListNode* a, ListNode* b) {
ListNode dummy(0);
ListNode* p = &dummy;
while (a && b) {
if (a->val <= b->val) {
p->next = a;
p = p->next;
a = a->next;
}
else {
p->next = b;
p = p->next;
b = b->next;
}
}
if (a) {
p->next = a;
}
if (b) {
p->next = b;
}
return dummy.next;
}
};
快速排序
class Solution {
public:
ListNode* sortList(ListNode* head) {
// each time select head
// larger : head->next = larger;
// smaller : smaller->next = head;
if (!head || !head->next) return head;
auto [left, right] = quickSort(head, nullptr);
return left;
}
tuple<ListNode*, ListNode*> quickSort(ListNode* begin, ListNode* end) {
if (begin == end) return {begin, end};
ListNode* left = begin;
ListNode* right = begin;
int target = begin->val;
ListNode* cur = begin->next;
while (cur != end) {
auto next = cur->next;
// 头插
if (cur->val < target) {
cur->next = left;
left = cur;
}
// 尾插
else {
right->next = cur;
right = cur;
}
cur = next;
}
right->next = end; // 防止死循环
auto [l1, r1] = quickSort(left, begin);
auto [l2, r2] = quickSort(begin->next, end);
// 链接
left = l1;
r1->next = l2;
right = r2;
return {left, right};
}
};