非比较排序
- 1、思想
不需要进行元素之间的比较,交换,在线性的时间内完成排序。 - 2、分类
1)计数排序
2)基数排序 - 3、优缺点
要求的空间比较多,是典型的以空间换时间的一种做法
计数排序
- 1、原理
- 2、代码实现
#include<iostream>
using namespace std;
void CountSort(int* a,int n)
{
//1、首先确定要开一个多大的用于统计的数组
int size = 0;
int min = a[0];
int max = a[0];
for(int i = 0; i<n; i++)
{
if(a[i] < min)
min = a[i];
if(a[i] > max)
max = a[i];
}
size = max-min+1;
//2、开始进行统计原数组中对应下标出现的数
int* count = new int[size];
memset(count,0,sizeof(int)*size);
for(int i = 0; i<n; i++)
{
count[a[i]-min]++;
}
//3、遍历哈希表,将count数组中大于0的数对应出原数组的值,
//写入原数组中
int j = 0;
for(int i = 0; i<size; i++)
{
while(count[i]--)
{
a[j++] = i+min;
}
}
delete[] count;
}
//测试函数
void TestCountSort()
{
int a[10] = {2,5,3,8,3,7,10,9,4,0};
int sz = sizeof(a)/sizeof(a[0]);
CountSort(a,sz);
for(int i = 0; i<sz; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
4、时间复杂度和空间复杂度
时间复杂度:O(N)
空间复杂度:O(k)(其中K为要排序的数组的范围)5、优缺点
1)缺点:由于计数排序的计数数组的大小是取决于数据的范围,那么当要进行排序的数据范围很大时,就需要大量的时间和内存。
2)优点:
A:无需进行比较,所以时间上快于任何的比较排序。
B:适用于数据比较集中的数据排序
基数排序
- 1、原理
- 2、分类:
LSD–从低位向高位排
MSD–从高位向低位排 - 3、代码实现
#include<iostream>
using namespace std;
//给一个数,求这个数有多少位
int GetDigit(int* a,size_t n)
{
int base = 10;
int digit = 1;
int num = 0;
for(int i = 0; i<n; i++)
{
while(a[i] >= base)
{
digit++;
base *= 10;
}
}
return digit;
}
void LSDdigit(int* a,int n)
{
int digit = GetDigit(a,n); //得到位数
int count[10] = {0};
int start[10] = {0};
int base = 1;
//开辟一个新的数组,用于存放一次排序后的数
int*temp = new int[n];
while(digit--)
{
//首先按各位进行统计个位上的数出现的次数
for(int i = 0; i<n; i++)
{
int num = (a[i]/base)%10;
count[num]++;
}
start[0] = 0;
for(int i = 1; i<10; i++)
{
start[i] = start[i-1]+count[i-1];
}
for(int i = 0; i<10; i++)
{
int num = (a[i]/base)%10;
temp[start[num]++] = a[i];
count[num]--;
}
for(int i = 0; i<10; i++)
{
a[i] = temp[i];
}
base *= 10;
}
delete[] temp;
}
//测试函数
void TestLSDdigit()
{
int a[10] = {73,22,93,43,55,14,28,65,39,81};
int sz = sizeof(a)/sizeof(a[0]);
LSDdigit(a,sz);
for(int i = 0; i<sz; i++)
{
cout<<a[i]<<" ";
}
cout<<endl;
}
- 4、时间复杂度和空间复杂度
时间复杂度:O(N*digit)
空间复杂度:O(N) 5、适用性
- 基数排序更适合用于对时间、字符串等这些整体权值未知的数据进行排序。
- 注意:基数排序如果从高位向低位排的话会很麻烦
6、缺点
由于是空间换取时间,按位进行排序,那么每一位的数的位置可能会发生巨大的变化,目前硬件的缓存不是很占优势,并且当内存比较宝贵的时候,就不要采取这种方式进行排序了。