基数排序:主要思想是把数字按位进行比较,从个位,十位... 到最高位,取得每个位的单个数字逐一进行比较和移动。
由于整数也可以用字符串表达(比如名字或日期)和特定格式的浮点数,所以基数排序也不是只能使用于整数,其他类型也可使用这种方式。
#include <stdio.h>
typedef struct _node
{
int m_value;
int m_base;
} node;
int process_data(node* pList, int len, int weight)
{
int nValue = 1;
int i=0;
int nFlag = 0;
// weight is start from 1
for (i=0; i< weight; i++)
{
nValue *= 10;
}
for (i=0; i < len; i++)
{
if (weight == 1)
{
(pList+i)->m_base = (pList+i)->m_value % nValue;
nFlag = 1;
}
else
{
// 此处主要用于处理负数情况
if ((pList+i)->m_value >= 0)
(pList+i)->m_base = -10;
else
(pList+i)->m_base = -11;
// 每次提取数字中的位数是在10的n次方和(n-1)次方之间
if ((((pList+i)->m_value < 0)&&((pList+i)->m_value*(-1) > (nValue/10)))
|| (((pList+i)->m_value > 0) && ((pList+i)->m_value > (nValue/10))))
{
(pList+i)->m_base = ((pList+i)->m_value%nValue)/(nValue/10);
nFlag = 1;
}
}
}
return nFlag;
}
void base_sort(int arr[], int len)
{
int i = 0;
int j = 0;
int nCnt = 0;
int nWeight = 1;
node* pData = (node*)malloc(len*sizeof(node));
node* pTmpList = (node*)malloc(len*sizeof(node));
for (i = 0; i < len; i++)
{
(pData+i)->m_value = arr[i];
(pData+i)->m_base = -10;
}
while(process_data(pData, len, nWeight))
{
nCnt = 0;
nWeight++;
for (j = -11; j < 10; j++)
{
for (i=0; i < len; i++)
{
if ((pData+i)->m_base == j)
{
(pTmpList+nCnt)->m_value = (pData+i)->m_value;
nCnt++;
}
}
}
memcpy(pData, pTmpList, sizeof(node)*len);
}
// finished the sort, re-copy the result
for (i=0; i < len; i++)
{
arr[i] = (pData+i)->m_value;
}
free(pData);
free(pTmpList);
}
int main()
{
int test1[] = {3, 90, -20, 156, 839, 98, 643,1,900, 66};
int i = 0;
for (i=0; i < 10; i++)
{
printf("%d ", test1[i]);
}
printf("\n\n");
base_sort(test1, 10);
for (i=0; i < 10; i++)
{
printf("%d ", test1[i]);
}
printf("\n\n");
scanf("%d", &i);
return 0;
}
基数排序的时间复杂度是 O(k·n),其中n是排序元素个数,k是数字位数。
再贴一段:
#include <iostream>
using namespace std;
int preprocess(int arr[], int nLen, int nWeight)
{
int i = 0;
int value = 1;
int nRet = 0;
for (i = 0; i < nWeight; i++)
value *= 10;
for (i = 0; i < nLen; i++)
{
arr[i] = arr[i] % value / (value / 10);
if (arr[i] > 0)
nRet = 1;
}
for (i = 0; i < nLen; i++)
{
cout << arr[i] << " ";
}
cout << endl;
return nRet;
}
void sortsignalpos(int arr[], int nLen)
{
int i = 0, j = 0;
int val = 0;
int *tmparr = (int*) malloc(sizeof(int) * nLen);
memset(tmparr, 0, sizeof(int)*nLen);
for (val = -9; val < 10; val++)
{
for(i = 0; i < nLen; i++)
{
if ((arr[i] != -10) && (arr[i] == val))
{
tmparr[j] = arr[i];
j++;
arr[i] = -10;
}
}
}
for (i=0; i < nLen ; i++)
{
cout << tmparr[i] << " ";
}
cout << endl;
memcpy(arr, tmparr, nLen*sizeof(int));
free(tmparr);
}
void basesort(int arr[], int nLen)
{
int i = 0, j = 0, k = 0;
int weight = 1;
int value = 1;
int *tmparr = (int*) malloc(sizeof(int) * nLen);
int *swaparr = (int*) malloc(sizeof(int) * nLen);
memcpy(tmparr, arr, nLen*sizeof(int));
memset(swaparr, 0, sizeof(int)*nLen);
while(true)
{
if (preprocess(tmparr, nLen, weight) == 0)
break;
value = 1;
for (i = 0; i < weight ; i++)
value *= 10;
sortsignalpos(tmparr, nLen);
k = 0;
for (i = 0; i < nLen; i++)
{
for (j = 0; j < nLen; j++)
{
if ((arr[j] != 0xffff) && ((tmparr[i] != -10) && (tmparr[i] == (arr[j] % value /(value / 10)) )))
{
swaparr[k] = arr[j];
tmparr[i] = -10;
k++;
arr[j] = 0xFFFF;
}
}
}
memcpy(arr, swaparr, nLen*sizeof(int));
memcpy(tmparr, swaparr, nLen*sizeof(int));
for (i=0; i < nLen ; i++)
{
cout << tmparr[i] << " ";
}
cout << endl;
weight++;
}
memcpy(arr, swaparr, nLen*sizeof(int));
free(tmparr);
free(swaparr);
tmparr = NULL;
swaparr = NULL;
}
int main()
{
int i = 0;
int test1[] = {3, 90, -20, 156, 839, 98, 643,1,900, 66};
int nLen = 10;
for (i=0; i < nLen ; i++)
{
cout << test1[i] << " ";
}
cout << endl;
basesort(test1, nLen);
for (i=0; i < nLen ; i++)
{
cout << test1[i] << " ";
}
cout << endl;
cin >> i;
return 0;
}