Vol8
排序:笔试和面试的重点.1.算法描述;2.实现;3.效率分析(时间复杂度,空间复杂度,稳定性)
稳定性:针对关键字相同的数据,排序前如果A在A"的前面,排序后还能保证A在A"的前面,则算法稳定,否则不稳定
稳定性判断依据:有没有跳跃的交换数据,没有则稳定
8.基数(桶)排序
代码思想:低位优先,将所有的数字,从低位(个位)开始到高位,依次进入相应的队列,再出,直到全部有序
时间复杂度:O(dn),d为位数
空间复杂度:O(n)
稳定性:稳定(没有数据交换)
//获取最大数字的位数
static int GetFigur(int *arr,int len)
{
int max=arr[0];//最大值
for(int i=1;i<len;i++)
{
if(max<arr[i])
max=arr[i];
}
//获取位数,丢个数 除10
int count=0;
while(max!=0)
{
max/=10;
count++;
}
return count;
}
//获取十进制整数从右往左第figure位的数
//例如(123,0)->3,(123,1)->1,(123,2)->1,(123,3)->0
static int GetNum(int n,int figur)
{
for(int i=0;i<figur;i++)
n/=10;
return n%10;
}
//基数排序
void RadixSort(int *arr,int len)//O(dn),d为位数,O(n),稳定(没有数据交换)
{
//需要利用10个队列,存放进队的数字
SqQueue queArr[10];
for(int i=0;i<10;i++)
{
InitQueue(&queArr[i]);
}
//得到最大数字的位数,确定进队和出队的趟数
int count=GetFigur(arr,len);
int index;//队列的下标
for(int i=0;i<count;i++)//处理每个数字从右往左的第i个数
{
for(int j=0;j<len;j++)//遍历数组,并入队
{
index=GetNum(arr[j],i);//index保存arr[j]应该进入的队列下标
Push(&queArr[index],arr[j]);//将数字存放到对应的队列
}
//所有数据出队,依次将所有队列的数据出队
int j=0;//arr下标
for(int k=0;k<10;k++)//所有队列
{
//一个队列可能有多个数据
while(!IsEmpty(&queArr[k]))
{
Pop(&queArr[k],&arr[j++]);
//j++;
}
}
}
for(int i=0;i<10;i++)
{
Destroy(&queArr[i]);
}
}