【练习3.13】
利用社会安全号码对学生记录构成的数组排序。编写一个程序进行这件工作,使用具有1000个桶的基数排序并且分三趟进行。
Answer:
首先,对社会安全号码不了解的就把它当成一个不超过9位的正整数就好了。
于是题目就是,通过1000个桶,对9位正整数进行桶排序。
因为一次最多比较三位(1000桶),刚好分三趟进行,加上最后复制回数组的一次,共遍历数组长度四次,时间复杂度O(N)
测试代码:

1 #include <iostream> 2 #include "linklist.h" 3 using namespace std; 4 using namespace linklist; 5 template class List<int>; 6 int main(void) 7 { 8 int numbers[] = { 111111111, 234543213, 298787536, 639383374, 212394837, 192837467, 81293874, 847920876, 908746573, 876418193 }; 9 bucketsort(numbers, 10); 10 for (auto elem : numbers) 11 cout << elem << endl; 12 13 system("pause"); 14 }
实现代码:
1 //练习3.13新增,4位数桶对不超过9位的正整数(社会安全号)桶排序 2 void bucketsort(int ssn[], int size) 3 { 4 //每次对三位数进行排序 5 List<int>* lastthree = new List<int>[1000]; 6 7 //初次排序时,遍历数组 8 //将每个元素后三位压入与之对应编号的链表 9 for (int i = 0; i != size; ++i) 10 lastthree[ssn[i] % 1000].additem(ssn[i]); 11 12 //以后的排序时,按顺序遍历前一个链表 13 //将元素的某三位压入与之对应编号的链表 14 List<int>* midthree = new List<int>[1000]; 15 for (int i = 0; i != 1000; ++i) 16 { 17 for (Node<int>* iter = lastthree[i].begin(); iter != nullptr; iter = iter->next) 18 midthree[(iter->data / 1000) % 1000].additem(iter->data); 19 } 20 delete[] lastthree; 21 List<int>* firstthree = new List<int>[1000]; 22 for (int i = 0; i != 1000; ++i) 23 { 24 for (Node<int>* iter = midthree[i].begin(); iter != nullptr; iter = iter->next) 25 lastthree[iter->data / 1000000].additem(iter->data); 26 } 27 delete[] midthree; 28 29 //排序完成后,按顺序遍历当前链表,并将元素依次复制入原数组 30 for (int i = 0, j = 0; i != 1000; ++i) 31 { 32 for (Node<int>* iter = lastthree[i].begin(); iter != nullptr; iter = iter->next) 33 ssn[j++] = iter->data; 34 } 35 delete[] lastthree; 36 }