计数排序(Counting-Sort):
基本思想: 确定比某一元素x小的元素的个数n,则排序后x所在的位置为n+1。
#define COUNTING_SIZE 100
void CountingSort(int *dat, int len) {
const size_t arr_len = len;
int *cnt = new int[COUNTING_SIZE];
int *buf = new int[arr_len];
memset(cnt, 0, sizeof(int) * COUNTING_SIZE);
for (int i = 0 ; i < len ; ++i) {
++cnt[dat[i]];
}
for (int i = 1 ; i < COUNTING_SIZE ; ++i) {
cnt[i] = cnt[i - 1] + cnt[i];
}
for (int i = 0 ; i < len ; ++i ) {
buf[cnt[dat[i]] - 1] = dat[i];
--cnt[dat[i]];
}
memcpy(dat, buf, sizeof(int) * len);
delete[] buf;
delete[] cnt;
}
基数排序(Radix-Sort):
基本思想:从最低位开始,对前k位排序,排完后对新数列的[k+1 -> 2k]位继续排序,循环累加k位排序,直到所有位都排完,得到结果。
void RadixSort(int *dat, int len, int max_int_len = 10) {
const size_t arr_len = len;
int *cnt = new int[10];
int *buf = new int[arr_len];
int base = 1;
for (int i = 0; i < max_int_len ; ++i, base *= 10) {
memset(cnt, 0, sizeof(int) * 10);
for (int j = 0 ; j < len ; ++j) {
++cnt[(dat[j] / base) % 10];
}
for (int j = 1 ; j < 10 ; ++j) {
cnt[j] = cnt[j] + cnt[j - 1];
}
for (int j = len - 1 ; j >= 0 ; --j ) {
buf[cnt[(dat[j] / base) % 10] - 1] = dat[j];
--cnt[(dat[j] / base) % 10];
}
memcpy(dat, buf, sizeof(int) * arr_len);
}
delete[] buf;
delete[] cnt;
}
桶排序(Bucket-Sort):
基本思想:根据高k位进行分组,例如:123->blist[1] ,1245->blist[12],332->blist[3] ,56->blist[0],,923->blist[9]等等。分组后对每一组进行排序,排序结束后,从小到大连接所有列表。#include<vector>
#include<algorithm>
#define LIST_SIZE 10
#define MAX_LENGTH 100
using namespace std;
void BucketSort(
int arr[], int len,
const int list_len = LIST_SIZE,
const int max_size = MAX_LENGTH) {
vector<int> blist[LIST_SIZE];
for (int i = 0 ; i < len ; ++i) {
blist[arr[i] / max_size].push_back(arr[i]);
}
for (int i = 0 ; i < list_len ; ++i) {
if (!blist[i].empty()) {
sort(blist[i].begin(), blist[i].end());
}
}
for (int i = 1 ; i < list_len ; ++i) {
if (!blist[i].empty()) {
blist[0].insert(blist[0].end(), blist[i].begin(), blist[i].end());
}
}
for (int i = 0 ; i < len ; ++i) {
arr[i] = blist[0][i];
}
}