排序篇-内部排序-桶排序+线性排序

158 阅读1分钟

桶排序

  • 基本思想 桶排序将要排序的数据按照一定的范围分到几个有序的桶里,没个桶里的数据在单独进行桶内排序。桶内排序完后,再把每个桶里的数据按照顺序依次取出,组成的序列就是有序的了。
  • 时间复杂度 桶内排序使用快排时,复杂度为O(n * log(n/m)) 其中m为桶的个数,当m较大时,复杂度接近线性
  • 应用场景 一般用于外部排序

计数排序

  • 基本思想 计数排序是桶排序的一种特殊情况。当要排序排序的n个数据,所处的范围不大时,我们可以把数据划分成k个桶,每个桶内的数据值都是相同的, 省掉了桶的内部排序。 计数排序只能给非负整数排序

  • 空间复杂度 O(k), 一般情况下k很小,可以认为是常量

  • 时间复杂度 O(n)

void countingSort(int *a, int n){
	if(n < 1) return;
    
    //查找最大值
    int i, max = a[0];
    for(i = 1; i < n; i ++){
    	if(max < a[i]) max = a[i];
    }

	// 申请一个计数数组c并置0
    int c[max + 1];
    memset(c, 0, sizeof(int) * (max + 1));
    
    // 计算每个元素的个数
    for(i = 0; i < n; i ++){
    	c[a[i]] ++;
    }
    
    // 计算前i个元素的和
    for(i = 1; i <= max; i ++){
    	c[i] = c[i] + c[i - 1];
    }
    
    // 临时数组r存储排序之后的结果
    int r[n];
    
    //计算排序
    for(i = n - 1; i >= 0; i --){
    	int index = c[a[i]] - 1;
        r[index] = a[i];
      	c[a[i]] --;  
    }
   	
    //将r中数组复制到a中
    memcpy(a, r, sizeof(int) * n);
}