计数排序:
找出数据中的最大值和最小值,并创建哈希表,把 数据-最小值 作为数组的下标访问哈希表并标记数量,标记完后,遍历哈希表,当表中的值大于0,把 **下标+最小值 (下标=元素-最小值)**还原数据依次放回数组中,是一种典型的以空间换时间的算法
该排序算法理论上速度非常快,它不是基于比较的算法,在一定范围内整数排序时快于任意的一种比较排序算法,但是有很大的局限性:适合排序整形数据,而且数据的范围差别不宜过大,否则会非常浪费内存反而慢于比较的排序,如果数据越平均、重复数越多,性价比越高
时间复杂度:Ο(N+k)(其中k是整数的范围)
稳定的
max-min+1=75,总共需要开辟的空间 //开辟足够大的空间
元素-min=元素的下标 //把数组从0开始
桶:
根据数据的值存储到不同的桶中,然后再调用其它的排序算法,对桶中的数据进行排序,然后再从桶中依次拷贝回数组中,从而降低排序的规模以此提高排序的速度,是一种典型的以空间换时间的算法
缺点:如何分桶、桶范围多大,这些都需要对数据有一定的了解
时间复杂度:Ο(N+k)
桶排序的稳定性取决于桶内排序使用的算法
基数:
是桶排序的具体实现,首先创建10个队列(链式队列),然后逆序计算出数据的个、十、百...位数,然后入到对应的队列中,结束后依次从队列中出队回数组中,数据下一位继续入队,依次循环,最大值的位数就是循环次数
缺点:只适合排序正整数数据,又要准备队列
时间复杂度:Ο(N+k)
稳定的
在这里插入代码片
```#include <stdio.h>
#include<stdbool.h>
#include<stdlib.h>
#include"queue.c"
#define swap(a,b) {typeof(a) t=(a);a=b;b=t;}
#define LEN 10
typedef void (*SortFP)(int *,int );
void show(int *,int );
//计数排序
void count_sort(int *arr,int len)
{
int min=arr[0];
int max=arr[0];
for(int i=0;i<len;i++)
{
if(arr[i]<min) min=arr[i];
if(arr[i]>max) max= arr[i];
}
//哈希表
//开辟max-min个空间
int *hash=calloc(sizeof(int),max-min+1);
//标记哈希表
for(int i=0;i<len;i++)
{
hash[arr[i]-min]++;
}
//还原到arr中
for(int i=0,j=0;i<=max-min;i++)
{
while(hash[i]--)
{
arr[j++]=i+min;
}
}
free(hash);
show(arr,len);
printf("%s\n",__func__);
}
//cnt 桶的数量 range桶中的数据范围
void _bucket_sort(int *arr,size_t len,int cnt ,int range)
{
//申请桶的内存
//bucket指向桶的开头,bucketend指向末尾,数据加入bucketend++;
//指针数组
int *bucket[cnt],*bucketend[cnt];
for(int i=0;i<cnt;i++)
{
//数据可能全部在一个桶
bucket[i]=malloc(sizeof(int)*len);
//开始时,起始,末尾指针都指向开头
bucketend[i]=bucket[i];
}
//把所有数据,按照桶的范围放入对应的桶中
for(int i=0;i<len;i++)
{
for(int j=0;j<cnt;j++)
{
if(arr[j]>=j*range && arr[j]<range*(j+1))
{
*(bucketend[j])=arr[i];
bucketend[j]++; //存入之后指针向后移动
}
}
}
//让每个桶的数据排序,分别存入arr中
for(int i=0;i<cnt;i++)
{
//计算每个桶中的元素
int size=bucketend[i]-bucket[i];
//如果有元素才需要别的算法
if(size>1)
{
count_sort(bucket[i],len);
}
memcpy(arr,bucket[i],sizeof(int)*size);
arr+=size;
free(bucket[i]);
}
}
//桶排序
void bucket_sort(int *arr,size_t len)
{
_bucket_sort(arr,len,4,25);
show(arr,len);
printf(":%s\n",__func__);
}
//基数排序
void radix_sort(int *arr,size_t len)
{
ListNode *queue[10]={};
for(int i=0;i<len;i++)
{
queue[i]=create_list_queue();
}
//循环次数由最大值的位数决定
int max=arr[0];
for(int i=0;i<len;i++)
{
if(arr[i]>max) max=arr[i];
}
//i是1表示个位,2表示十位,3表示百位
for(int i=1,k=1;max/k>0;k*=10,i++)
{
int mod=pow(10,i);
int div=mod/10;
for(int j=0;j<len;j++)
{
//获取每位的值,如果mod过大,数据的index是0
int index=arr[j]%mod/div;
push_list_queue(queue[index],arr[j]);
}
int k=0;
for(int j=0;j<10;j++)
{
//把队列中的数据按顺序放回arr
while(!empt_list_queue(queue[j]))
{
arr[k++]= hea_list_queue(queue[j]);
pop_list_queue(queue[j]);
}
}
}
show(arr,len);
printf(":%s\n",__func__);
}
int main(int argc,const char* argv[])
{
int arr[LEN]={};
SortFP sort[]={bubble_sort,Select_sorting,insertion_Sort2,shell_Sort2,quick_sort,sort_heap,sort_heap_r,count_sort,bucket_sort,radix_sort};
for(int i=0;i<sizeof(sort)/sizeof(sort[0]);i++)
{
for(int j=0;j<LEN;j++)
{
arr[j]=rand()%100;
printf("===");
}
printf("\n");
show(arr,LEN);
printf("排序前\n");
sort[i](arr,LEN);
}
//bubble_sort(arr,n); //冒泡
//Select_sorting(arr,n);//选择排序
//shell_sort(arr,n); //希尔排序
//insertion_Sort(arr,n); //插入排序
//quick_sort(arr,n); //快速排序
//int reg[6]={};
// Merge_sort(arr,reg,0,n-1);//归并排序
/* int arr[]={3,100,22,0,2,5,6,73,6,9,22,16,88,7};
sort_heap(arr,14);
for(int i=0;i<14;i++)
{
printf("%d ",arr[i]);
}
printf("\n");*/
return 0;
}