排序算法,扩展到List上面,除了需要随机访问,均可以实现。如 归并排序,插入排序,选择排序,快排等。下面依依列出几个。
Insertion Sort List
Sort a linked list using insertion sort.
题目:实现链表的插入排序。分析:插入排序比较简单,假定一个节点有序的,后面的节点在前面的有序列中找到合适的位置插入。
代码:思想比较简单,关键是思路清楚,定义几个变量保存之后或之前的指针。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *insertionSortList(ListNode *head) {
if(head==NULL || head->next==NULL) return head;
ListNode *hhead=new ListNode(INT_MIN);//定义头指针,对于插入到最前边的元素有用
hhead->next=head;
ListNode *cur=head->next;
ListNode *oredered_last=head;//有序序列的最后一个元素,一定是cur的pre元素,用于删除当前的元素,连接链表。
while(cur){
if(cur->val >= oredered_last->val){//4 5 6 1 2,扫描到6,直接后移,如果是排好序的
oredered_last=cur;
cur=cur->next;
}else{
ListNode *t=cur;
cur=cur->next;
ListNode *ph=hhead;
while((ph->next->val <= t->val) && ph->next!=cur){//从前往后找可以 可以插入的位置
ph=ph->next;
}
oredered_last->next=cur;//del t
t->next=ph->next;
ph->next=t;
}
}//cur
return hhead->next;
}
};
Sort List
Sort a linked list in O(n log n) time using constant space complexity.
题目:链表排序,要求时间复杂度 O(n log n)。
分析:归并排序,快排时间复杂度最坏的情况下是O(n^2)
代码:
/**
* 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 *slow=head;
ListNode *fast=head->next;
while(fast && fast->next){
slow=slow->next;
fast=fast->next->next;
}
fast=slow->next;
slow->next=NULL;//快慢指针,将链表分成两段
ListNode *m1=sortList(head);
ListNode *m2=sortList(fast);
return merge(m1,m2);
}
ListNode* merge(ListNode *m1, ListNode *m2){
if(m1==NULL) return m2;
if(m2==NULL) return m1;
ListNode *l1=m1;
ListNode *l2=m2;
ListNode *p=NULL;
ListNode *retres;
while(true){
if(l1 && l2){
if(l1->val <= l2->val){
if(p==NULL){
p=l1; retres=p;
}else{
p->next=l1; p=p->next;
}
l1=l1->next;
}else{
if(p==NULL){
p=l2; retres=p;
}else{
p->next=l2; p=p->next;
}
l2=l2->next;
}
}else if(l1){//l1不空 l2空
p->next=l1;
break;
}else if(l2){
p->next=l2;
break;
}else{
break;
}
}//while
return retres;
}
};
Partition List
Given a linked list and a value x, partition it such that all nodes less than x come before nodes greater than or equal to x.
You should preserve the original relative order of the nodes in each of the two partitions.
For example,
Given 1->4->3->2->5->2
and x = 3,
return 1->2->2->4->3->5
.
分析:从前往后扫描,大于x的 不动,小于x,插入到小于x序列末尾。快排的部分。
代码:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *partition(ListNode *head, int x) {
if(head==NULL || head->next==NULL) return head;
ListNode *hhead=new ListNode(INT_MIN);//头指针
hhead->next=head;
ListNode *pre=hhead;//小于x的序列的末尾
ListNode *beforecur=hhead;//cur的前一个值
ListNode *cur=head;
while(cur && cur->val < x ){//找到第一个大于x的值
cur=cur->next;
pre=pre->next;
beforecur=beforecur->next;
}
while(cur){
if(cur->val >= x) {
beforecur=beforecur->next;
cur=cur->next;
}else{
ListNode *t=cur;
cur=cur->next;
//delete t
beforecur->next=cur;
//insert t到小于x的序列中
t->next=pre->next;
pre->next=t;
pre=t;
}
}
return hhead->next;
}
};