基数排序基于多关键字排序的思想,即把一个逻辑关键字拆分成多个关键字。
基数排序有两种实现方式:
- 第一种叫做最高位优先(MSD),即先按最高位排成若干子序列,再对每个子序列按次高位排。
- 第二种叫做最低位优先(LSD),这种方式不必分成子序列,每次排序全体元素都参与。最低位可以优先这样进行,不通过比较,而是通过“分配”和“收集”。
由于不需要分堆并对每堆单独排序,LSD方法往往比MSD简单而开销小。
基数排序适合的场景是序列中的元素很多,但组成元素的关键字的取值范围较小。如果关键字的取值范围也很大,如26个字母,且序列中大多数元素的最高位关键字都不相同,那么这时可以考虑使用“最高位优先法”,先根据最高位排成若干个子序列,然后分别对这些子序列进行直接插入排序。
感觉桶排序与基数排序貌似是一样的。【待解决】
算法代码为:
写了好久,归根结底还是链表、指针的不熟悉造成的,加油!
#include "stdafx.h"
#include <iostream>
using namespace std;
//链表使用功底有待加强!!
struct Node
{
int value;
Node *next;
};
int getDigit(int num, int loc)
{//取数字num第loc位上的数字
for(int i=0; i < loc; i++)//i从0开始
num /= 10;
return num%10;
}
int maxBits(int data[], int size)
{//数组中数字的最大位数;相当于进行几趟分配
int max = 0, temp, current;
for(int i=0; i<size; i++)
{
temp = 0;
current = data[i];
while(current)
{
temp++;
current /= 10;
}
if(temp > max)
max = temp;
}
return max;
}
void RadixSort(int data[], int size)
{//其实应该还可以有个表示基数的参数,现在默认为10
if(data == NULL || size <= 0)
return;
int rankNum = maxBits(data, size);
Node Bucket[10];//建立10个桶
if(Bucket == NULL)
return ;
int i,idNum;
Node *p,*q;//插入节点时所用的临时变量
for(int rank = 0; rank < rankNum; rank++)
{//进行rankNum趟排序
for(int i = 0; i < 10; i++)
{//初始化桶
Bucket[i].value = -1;
Bucket[i].next = NULL;
}
for(int i = 0; i < size; i++)
{//依次如桶
Node *pNew = new Node();//()表示值初始化
pNew->value = data[i];
pNew->next = NULL;
idNum = getDigit(data[i],rank);
if(Bucket[idNum].next == NULL)
Bucket[idNum].next = pNew;
else
{
p = &Bucket[idNum];//注意&
while(p->next != NULL)
p = p->next;
p->next = pNew;
}
}
int j=0;//初始化
for(i=0; i < 10; i++)
{//依次遍历10个桶
p = Bucket[i].next;
if(p == NULL)
continue;
while(p != NULL)
{
data[j++] = p->value;
q = p;
p = p->next;
delete q;//勿忘释放空间!!
}
}
for(int i=0;i<size;++i)
cout<<data[i]<<" ";
cout<<endl;
}
}
int main()
{
int unsorted[] = {3,36,1,4,15,5,8,14,9,9,10};
int length = sizeof(unsorted)/sizeof(int);
for(int i=0;i<length;++i)
cout<<unsorted[i]<<" ";
cout<<endl;
RadixSort(unsorted,length);
for(int i=0;i<length;++i)
cout<<unsorted[i]<<" ";
cout<<endl;
return 0;
}
写在最后:其实,这些经典的算法的思想,都是非常熟悉的,但,知道容易动手难,尤其是最后这个基数排序卡了很久,还是多动手吧,无他,唯手熟尔!