左神算法基础class2—题目7、8桶排序之计数排序及其应用
1.计数排序
假设共有15个数,范围为(0-9),不用比较把所有数排好。
介绍
1.计数排序是一个非基于比较的排序算法与被排序的样本的实际数据状况很有关系,所
以实际中并不经常使用
2.时间复杂度O(N),额外空间复杂度O(N)
3.稳定的排序
分析
1.准备长度与数值范围相同的桶——10个桶(数值0-9)
2.遍历数组,数值为a时,把桶内位置为a的数加一
3.重构数组
核心代码
遍历:a[]是辅助数组,作为桶用来统计次数;arr[i]是原始数组。把原始数组的值作为桶的序号位置,桶在此位置的值加一。
for(int i = 0;i < arr_Length;i++)
{
a[arr[i]]++;
}
完整代码
#include <iostream>
using namespace std;
#include<time.h>
#define arr_Length 15
int main()
{
//生成随机数
srand((unsigned)time(NULL));
int arr[arr_Length];
cout << "原数组arr: ";
for(int i = 0;i < arr_Length;i++)
{
arr[i] = rand()%10;
cout << arr[i]<< ' ';
}
cout << endl <<endl;
//准备桶 O(n)
int a[arr_Length] = {
0};
//遍历O(n)
for(int i = 0;i < arr_Length;i++)
{
a[arr[i]]++;
}
//重构O(n)
for(int i = 0;i < arr_Length;i++)
{
if(a[i] != 0)
cout<<a[i]<<"个"<<i<<endl;
}
system("pause");
return 0;
}
2.应用:给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度O(N),且要求不能用非基于比较的排序。【随机生成9个数,范围在0-99】
分析
1.假设共有N个数,准备N+1个桶。遍历找到数组的最小值和最大值,分别放在0位置和最后一个位置。将数组中最大值和最小值之间的值分为N+1等分(N+1个桶)。
2.准备三个长度为N+1的数组,分别为num_max[],num_min[] ,num_empty[]。表示当前位置桶内的最大值、最小值和桶是否为空。再把数组填入N+1个桶中,更新最大值、最小值。填完后必然存在一个空桶(N+1个桶,N个数)。
3.从1号桶开始,如果桶为空则继续下一个,若桶非空找前一个非空桶的最大值和当前桶的最小值求差值。遍历过后最大值即为所求。
Tips1:不能只找空桶两边的数,虽然同一桶内的差值小于空桶之间的差值,但是空桶两侧不一定为最大值。eg假设10个为桶的范围 19 (10-19) | 空(20-29) | 30(30-39) | 49(40-49),此时最大值为19。
Tips1:若max==min 所有数组值一样返回0。
核心代码
1.找出整个数组的min和max
int min = arr[0];
int max = arr[0];
for(</