Sort a linked list in O(n log n) time using constant space complexity.
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
这道题我着实花了不少时间完成,题目对于熟练数据结构的人应该很容易。
O(nlogn)的排序主要有:快速排序,堆排序,归并排序
这里我选择的归并排序,我发现其实链表这种数据结构在合并的时候效率比常规的数组效率要高一点,挺合适的。
参考:http://blog.csdn.net/jiadebin890724/article/details/21334059
这道题的关键在于链表的中间位置寻找和合并操作。
中间位置寻找直接用快慢指针就可以了,但是由于是要拆成两个链表,所以慢指针的位置其实第二条链表的head,这个head的前一个Node需要至next为NULL,所以在处理的时候得在加一个临时存储慢指针next前的位置;合并链表其实比想象中容易的多。
#include <iostream>
#include <list>
using namespace std;
struct ListNode {
int val;
ListNode *next;
ListNode(int x) : val(x), next(NULL) {}
};
void DisplayList(ListNode *head)
{
ListNode *temp = head;
while (temp)
{
std::cout << temp->val << ' ';
temp = temp->next;
}
}
class Solution {
public:
ListNode *listmid(ListNode *head)
{
ListNode *fast = head;
ListNode *slow = head;
ListNode *temp = NULL;
while (fast && fast->next)
{
fast = fast->next->next;
temp = slow;
slow = slow->next;
}
temp->next = NULL;
/*
DisplayList(head);
cout << 'a';
DisplayList(slow);
cout << 'b' << endl;
*/
return slow;
}
ListNode *merge(ListNode *left, ListNode *right)
{
ListNode *temp = new ListNode(0);
ListNode *p = temp;
/*
cout << "left:";
DisplayList(left);
cout << endl << "right:";
DisplayList(right);
cout << endl;
*/
while (left && right)
{
if (left->val <= right->val)
{
p->next = left;
left = left->next;
}
else
{
p->next = right;
right = right->next;
}
p = p->next;
}
if (left == NULL)
p->next = right;
else
p->next = left;
p = temp->next;
temp->next = NULL;
/*
DisplayList(p);
cout << endl;
*/
delete temp;
return p;
}
ListNode *mergesort(ListNode *head)
{
if (!head || !head->next)
return head;
ListNode *mid = listmid(head);
ListNode *left = mergesort(head);
ListNode *right = mergesort(mid);
return merge(left, right);
}
ListNode *sortList(ListNode *head) {
if (!head || !head->next)
return head;
return mergesort(head);
}
};
bool InsertList(ListNode *head, int num)
{
ListNode *newnode = new ListNode(0);
if (newnode == NULL)
return false;
ListNode *h = head;
while (h->next)
{
h = h->next;
}
h->next = newnode;
newnode->val = num;
newnode->next = NULL;
return true;
}
int main()
{
int num[5] = { 5, 4, 3, 2, 1 };
ListNode *lhead = new ListNode(0);
lhead->next = NULL;
lhead->val = num[0];
for (int i = 1; i < 5; i++)
InsertList(lhead, num[i]);
Solution sl;
DisplayList(sl.sortList(lhead));
system("PAUSE");
return 0;
}