题目的主要大意是对链表在O(nlogn)的时间复杂度和常量空间复杂度进行排序。排序依然采用的是快排的算法思想,另外,链表可以特殊处理元素相等的情况
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *sortList(ListNode *head) {
if(head== NULL || head->next == NULL)
return head;
ListNode *tail = head;
while(tail->next != NULL)
tail = tail -> next;
quicksort(head, tail);
return head;
}
void quicksort(ListNode* &head, ListNode* &tail)
{
ListNode *leftend = NULL;
ListNode *rightbegin = tail->next;
ListNode *end = tail->next;
ListNode *mid = head;
partition(head, tail, leftend);
if(leftend != NULL && leftend != head)
quicksort(head, leftend);
while(mid->next != end && mid->val == mid->next->val) //数值相等的节点不必再次排序
{
mid = mid->next;
}
rightbegin = mid->next;
if(rightbegin != end && rightbegin != tail)
quicksort(rightbegin, tail);
mid->next = rightbegin;
}
void partition(ListNode* &left, ListNode* & right, ListNode* & leftend)
{
ListNode *iterator = left->next; //遍历需要排序数组的迭代器
ListNode *mid = left; //中心节点
ListNode *prev = mid; // 记录保存在右边的节点的前驱
ListNode *temp = NULL; //存储交换过程中的节点
bool existLeftNode = false;
while (iterator != right)
{
if(mid->val == iterator->val) //数值相等的节点特殊处理 连接在mid节点后面
{
if(prev == mid)
{
prev = iterator;
iterator = iterator->next;
continue;
}
temp = iterator;
prev->next = iterator->next;
iterator = iterator->next;
temp->next = mid->next;
mid->next = temp;
}
else if (mid->val > iterator->val) //在最前面插入节点
{
temp = iterator;
prev->next = iterator->next;
iterator = iterator->next;
temp->next = left;
left = temp;
if(!existLeftNode)
{
existLeftNode = true;
leftend = temp;
}
}
else //不做改变,遍历下一个节点
{
prev = iterator;
iterator = iterator->next;
}
}
if(right->val < mid->val) //假如最后一个节点比中心节点小
{
prev->next = right->next;
right = prev;
iterator->next = left;
left = iterator;
if(!existLeftNode)
{
existLeftNode = true;
leftend = iterator;
}
}
}
};