1 基数排序介绍
基数排序是一种用在老式穿卡机上的算法。
该算法在对每一位数进行排序的时候需要是稳定的:
在该为相同的数的相对顺序不会变.因此可以使用上节的计数排序作为其子程序.
下边演示一个基数排序的过程:
2 基数排序的过程
计数排序的过程很简单。即从最低位到最高位的每一位进行计数排序.
3 算法实现
#ifndef __RADIXSORT_H__
#define __RADIXSORT_H__
#include <malloc.h>
#include <time.h>
#include <stdlib.h>
class Radixsort
{
int* m_data_input;
int* m_data_output;
int* m_data_tmp;
int* m_counter;
int m_size;
int m_max;
public:
Radixsort(int size,int maxValue);
~Radixsort();
void Create();
void Sort();
bool Counter(int digit);
bool Verify();
void OutputResult();
};
#endif
#include "Radixsort.h"
#include <stdio.h>
Radixsort::Radixsort(int size ,int maxValue)
{
m_size = size;
m_max = maxValue;
m_data_input = (int*)malloc(sizeof(int)* size);
m_data_output = (int*)malloc(sizeof(int)* size);
m_data_tmp = (int*)malloc(sizeof(int)* size);
m_counter = (int*)malloc(sizeof(int)* maxValue);
}
Radixsort::~Radixsort()
{
if(m_data_input)
{
free(m_data_input);
free(m_data_output);
free(m_counter);
free(m_data_tmp);
}
}
void Radixsort::Create()
{
srand((unsigned)time(NULL));
for(int i=0;i< m_size;i++)
{
m_data_input[i] = rand() % m_max;
}
}
bool Radixsort::Counter(int digit)
{
bool bContinue = false;
for(int i=0;i<10;i++)
{
m_counter[i] = 0;
}
for(int j=0;j<m_size;j++)
{
int tmp = m_data_input[j] / digit;
m_data_tmp[j] = tmp % 10;
m_counter[m_data_tmp[j]]++;
if(tmp)
{
bContinue = true;
}
}
for(int i=1;i<10;i++)
{
m_counter[i] = m_counter[i] + m_counter[i-1];
}
for(int v = m_size-1;v>=0;v--)
{
m_data_output[m_counter[m_data_tmp[v]]-1] = m_data_input[v];
m_counter[m_data_tmp[v]]--;
}
if(bContinue)
{
int* tmp = m_data_output;
m_data_output = m_data_input;
m_data_input = tmp;
}
return bContinue;
}
void Radixsort::Sort()
{
int digit = 1;
while(Counter(digit))
{
digit *=10;
}
}
bool Radixsort::Verify()
{
int oldValue = m_data_output[0];
for(int i=1;i<m_size;i++)
{
if(m_data_output[i]<oldValue)
{
return false;
}
oldValue = m_data_output[i];
}
return true;
}
void Radixsort::OutputResult()
{
for(int i=0;i<m_size;i++)
{
printf("%d \n",m_data_output[i]);
}
}
#include "Radixsort.h"
#include <stdio.h>
int main()
{
int maxValue = 1000;
int size = 20;
Radixsort pSort(size,maxValue);
pSort.Create();
pSort.Sort();
if(pSort.Verify())
{
printf("Success ! \n");
pSort.OutputResult();
}
else
{
printf("Error ! \n");
}
return 0;
}
4 性能分析
基数排序不是基于比较的排序,其运行时间为O(n),这是好于快速排序的平均情况O(nlgn).
但是其隐藏的常数因子通常要比快速排序大很多.并且它不是原地排序。因此基数排序只在排序规模很大
但又内存足够的时候才会有一定优势。