题目来源。待字闺中。原创@陈利人 。欢迎大家继续关注微信公众账号“待字闺中”
分析:思路和数据的高速排序一样,都须要找到一个pivot元素、或者节点。
然后将数组或者单向链表划分为两个部分。然后递归分别快排。
针对数组进行快排的时候,交换交换不同位置的数值。在分而治之完毕之后,数据就是排序好的。那么单向链表是什么样的情况呢?除了交换节点值之外。是否有其它更好的方法呢?能够改动指针,不进行数值交换。这能够获取更高的效率。
在改动指针的过程中。会产生新的头指针以及尾指针,要记录下来。在partition之后,要将小于pivot的的部分、pivot、以及大于pivot的部分又一次串起来成为一个singly linked list。
在partition时。我们用最后的节点作为pivot。当我们扫描链表时,假设节点值大于pivot,将节点移到尾部之后;假设节点小于。保持不变。
在递归排序时。我们先调用partition将pivot放到正确的为止并返回pivot,然后。递归左边。递归右边。最后在合成一个单链表。
详细代码例如以下:
#include <iostream> #include <map> #include <vector> #include <assert.h> using namespace std; struct node { int data; struct node* next; node(int x):data(x),next(NULL){} }; node* partition(node* start,node* end,node** newHead,node** newEnd) { node* provit = end,*tmp = NULL,*pre = NULL; while(start != provit) { if(start->data > provit->data) { tmp = start->next; if(pre)pre->next = tmp; start->next = NULL; end->next = start; end = start; start = tmp; } else { if(*newHead == NULL)*newHead = start; pre = start; start = start->next; } } if(*newHead == NULL)*newHead = provit; *newEnd = end; return provit; } node* GetTail(node* head) { if(head == NULL)return NULL; while(head->next != NULL)head = head->next; return head; } node* QuickSort(node* head,node* end) { if(head == NULL || head == end)return head; node* newHead = NULL,*newEnd = NULL;//此处不能用二维指针。不然partition调用*newHead解引用时会出错 node* provit = partition(head,end,&newHead,&newEnd); if(newHead != provit) { node* tmp = newHead; while(tmp->next != provit)tmp = tmp->next; tmp -> next = NULL; newHead = QuickSort(newHead,tmp); tmp = GetTail(newHead); tmp->next = provit; } if(provit != newEnd) { provit->next= QuickSort(provit->next,newEnd); } return newHead; } void QuickSort(node** head) { if(head == NULL)return; *head = QuickSort(*head,GetTail(*head)); } void printLink(node* head) { while(head != NULL) { cout << head->data <<" "; head = head->next; } cout << endl; } int main() { int n,i,value; node* head,*q; cin >> n; for(i=0;i<n;i++) { cin >> value; if(i == 0) { head = new node(value); q = head; } else { node* p = new node(value); q->next = p; q = p; } } printLink(head); QuickSort(&head); printLink(head); return 0; }
leetcode之
Sort List
Sort
a linked list in O(n log n)
time using constant space complexity.
该题用上面的方法会超时,能够使用归并排序
class Solution { public: ListNode *sortList(ListNode *head) { if(!head || !head->next)return head; ListNode* fast = head -> next -> next;//至少有两个节点 ListNode* slow = head; while(fast) { fast = fast->next; slow = slow->next; if(!fast)break; fast = fast->next; } ListNode* p = slow -> next; slow -> next = NULL; ListNode* q = sortList(head); p = sortList(p); head = NULL; ListNode* tail = NULL; while(q && p) { if(q->val > p->val) { if(!head)head = tail = p; else { tail->next = p; tail = tail->next; } p = p->next; } else { if(!head)head = tail = q; else { tail->next = q; tail = tail->next; } q = q->next; } } if(p) { if(!head)head = tail = p; tail->next = p; } if(q) { if(!head)head = tail = q; else tail->next = q; } return head; } };