计数排序:
找出数据中的最大值和最小值,并创建哈希表,把 数据-最小值 作为数组的下标访问哈希表并标记数量,标记完后,遍历哈希表,当表中的值大于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++){//把队列中的数据按顺序放回arrwhile(!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;
}