一、冒泡排序
class Solution {
public:
ListNode* sortList(ListNode* head) {
ListNode* dummpyHead = new ListNode(-1);
dummpyHead->next = head;
ListNode* temp = dummpyHead;
int len = 0;
//统计链表长度,顺便进行将最大值放在末尾
while (temp->next && temp->next->next) {
if (temp->next->val > temp->next->next->val) {
ListNode* node = temp->next;
temp->next = node->next;
node->next = node->next->next;
temp->next->next = node;
}
temp = temp->next;
len++;
}
//再进行n-1次排序,依此把最大值后移
for (int i = 0; i < len - 1; i++) {
temp = dummpyHead;
while (temp->next->val && temp->next->next->val) {
if (temp->next > temp->next->next) {
ListNode* node = temp->next;
temp->next = node->next;
node->next = node->next->next;
temp->next->next = node;
}
temp = temp->next;
}
}
return dummpyHead->next;
}
};
二、归并排序
归并排序需要注意节点的断开。
class Solution {
public:
ListNode* sortList(ListNode* head) {
return sortList(head, nullptr);
}
ListNode* sortList(ListNode* head, ListNode* tail) {
if (head == nullptr)return head;
//注意把节点断开
if (head->next == tail) {
head->next = nullptr;
return head;
}
ListNode*slow = head, *fast = head->next;
//快慢指针找中点
while (fast != tail) {
slow = slow->next;
if (fast->next != tail) {
fast = fast->next->next;
}
else {
break;
}
}
ListNode* mid = slow;
ListNode* head1 = sortList(head, mid);
ListNode* head2 = sortList(mid,tail);
return merge(head1, head2);
}
//合并两个有序链表
ListNode* merge(ListNode* l1, ListNode* l2) {
ListNode* head = new ListNode(-1);
ListNode* temp = head;
while (l1 || l2) {
if (l1 == nullptr) {
temp->next = l2;
break;
}
if (l2 == nullptr) {
temp->next = l1;
break;
}
if (l1->val <= l2->val) {
temp->next = l1;
l1 = l1->next;
}
else {
temp->next = l2;
l2 = l2->next;
}
temp = temp->next;
}
return head->next;
}
};
三、快速排序
class Solution {
private:
vector<ListNode*>vec;
public:
void sort(int left, int right) {
if (left < right) {
//随机选取一个位置作为标兵,放在对应位置
int ran = rand() % (right - left + 1) + left;
swap(vec[ran], vec[right]);
int privot = vec[right]->val;
int i = left - 1;
for (int j = left; j < right; ++j) {
if (vec[j]->val <= privot) {
i++;
swap(vec[i], vec[j]);
}
}
swap(vec[i + 1], vec[right]);
int pos = i + 1;
//跳过与标兵位置相同的值
int rNum = pos - 1;
int lNum = pos + 1;
while (rNum >= left && vec[rNum]->val == vec[pos]->val) {
rNum--;
}
while (lNum <= right && vec[lNum]->val == vec[pos]->val) {
lNum++;
}
//进行下一次排序
sort(left, rNum);
sort(lNum, right);
}
}
ListNode* sortList(ListNode* head) {
srand((unsigned)time(NULL));
if (head == nullptr)return head;
//把链表的节点放入数组并使用快速排序
ListNode* temp = head;
while (temp) {
vec.push_back(temp);
temp = temp->next;
}
int n = vec.size();
sort(0, n - 1);
//把排好序的数组还原成链表
ListNode* dummyHead = new ListNode(-1);
temp = dummyHead;
for (int i = 0; i < n; i++) {
temp->next = vec[i];
temp = temp->next;
}
temp->next = nullptr;
return dummyHead->next;
}
};
四、堆排序
class Solution {
private:
vector<ListNode*>vec;
public:
void maxHeap(int i, int len) {
for (; i * 2 + 1 <= len;) {
int large = i;
if (i * 2 + 1 <= len && vec[i * 2 + 1]->val > vec[large]->val) large = i * 2 + 1;
if (i * 2 + 2 <= len && vec[i * 2 + 2]->val > vec[large]->val)large = i * 2 + 2;
if (large == i) {
break;
}
else {
swap(vec[i], vec[large]);
i = large;
}
}
}
void buildHeap() {
int len = vec.size() - 1;
for (int i = len / 2; i >= 0; --i) {
maxHeap(i, len);
}
}
void sort() {
buildHeap();
int len = vec.size() - 1;
for (int i = len; i >= 0; --i) {
swap(vec[i], vec[0]);
len--;
maxHeap(0, len);
}
}
ListNode* sortList(ListNode* head) {
if (head == nullptr)return nullptr;
//把链表的节点放入数组并使用堆排序
ListNode* temp = head;
while (temp) {
vec.push_back(temp);
temp = temp->next;
}
int n = vec.size();
sort();
//把排好序的数组还原成链表
ListNode* dummyHead = new ListNode(-1);
temp = dummyHead;
for (int i = 0; i < n; i++) {
temp->next = vec[i];
temp = temp->next;
}
temp->next = nullptr;
return dummyHead->next;
}
};
五、放入数组使用sort()排序
class Solution {
public:
ListNode* sortList(ListNode* head) {
vector<ListNode*>vec;
ListNode* temp = head;
while (temp) {
vec.push_back(temp);
temp = temp->next;
}
sort(vec.begin(), vec.end(), [](ListNode* a, ListNode* b) {
return a->val < b->val; //这里用小于,如何是等于很多相等的还要移动
});
ListNode* dummyHead = new ListNode(-1);
temp = dummyHead;
for (int i = 0; i < vec.size(); i++) {
temp->next = vec[i];
temp = temp->next;
}
temp->next = nullptr;
return dummyHead->next;
}
};
六、multimap进行排序
class Solution {
public:
ListNode* sortList(ListNode* head) {
//把<值,节点>插入multimap的过程是一个红黑树,因此会自动按照键值排序
ListNode* temp = head;
multimap<int, ListNode*>map;
while (temp) {
map.insert({ temp->val,temp });
temp = temp->next;
}
//把排好序的节点连接起来
ListNode* dummyHead = new ListNode(-1);
ListNode* curr = dummyHead;
for (auto it = map.begin(); it != map.end(); it++) {
curr->next = (*it).second;
curr = curr->next;
}
curr->next = nullptr;
return dummyHead->next;
}
};
七、总结
六种方法都是普通排序数组可以用到的方法,这里套用在排序链表上。其中冒泡排序的时间复杂度很高不能通过,其他均可通过。