基排序
基排序 / 桶排序 / 数字排序
原理¶
需要频繁进行分组重排,(类似于归并)适用于链表
可分为两种:
-
MSD,最高位优先(Most Significant Digit first)
-
LSD,最低位优先 (Least Significant Digit first)
代码¶
//Definition for singly-linked list.
struct ListNode {
int val;
ListNode *next;
ListNode() : val(0), next(nullptr) {}
ListNode(int x) : val(x), next(nullptr) {}
ListNode(int x, ListNode *next) : val(x), next(next) {}
};
class Solution {
public:
ListNode* sortList(ListNode* head)
{
ListNode* dummyhead=new ListNode(0,head);
ListNode* p=dummyhead;
while(p->next!=nullptr)
{
p->next->val+=100000;
p=p->next;
}
vector<queue<ListNode*>>vec(10); //按0~9分组
for(int i=1;i<=100000;i*=10) //这里是6位数,共6趟
{
int flag=0;
while(dummyhead->next!=nullptr)
{
if(dummyhead->next->val/(i*10)!=0)
flag=1;
vec[dummyhead->next->val/i%10].push(dummyhead->next);
dummyhead->next=dummyhead->next->next;
}
ListNode* p=dummyhead;
for(int j=0;j<10;++j) //将每个组节点连接起来
{
while(!vec[j].empty())
{
vec[j].front()->next=p->next;
p->next=vec[j].front();
p=p->next;
vec[j].pop();
}
}
if(flag**0)
break;
}
p=dummyhead;
while(p->next!=nullptr)
{
p->next->val-=100000;
p=p->next;
}
ListNode* ret=dummyhead->next;
delete dummyhead;
return ret;
}
};
复杂度¶
设有
- 链表初始化的时间复杂度:
; - 分配的时间复杂度:
; - 分配后收集的时间复杂度:
;
则链式基数排序的时间复杂度为:
在排序过程中使用的辅助空间是:
则空间复杂度为:
-
当 n 很大,d 比较小小,基数排序可以比归并、快排性能更好
-
基排序是稳定排序。