《算法二》(希尔排序+基数排序+桶排序)
排序算法:shell排序/基数排序/桶排序
shell排序:
1.优化后的插入排序
2.按步长step分组:步长一开始设置为元素个数/2
3.组内插入排序
4.步长=步长/2
基数排序:
1.创建临时数组
2.初始化临时数组
3.临时数组排序
4.将临时数组值赋值回原数组
5.delete临时数组
限制:1.不能有重复运算
2.空间浪费大
优点:不需要经过比较
桶排序:基数排序的升级
1.根据数据范围获取排序次数
2.制作桶并且初始化
3.遍历a数组并且按照排序依据将a数组元素存到桶里
4.放回原来数组里
总结:希尔排序速度快,不稳定
桶排序速度快,稳定,但是空间复杂度高
代码演示:
1.希尔排序:
# include<iostream>
# include<vector>
#define NUM 10
using namespace std;
void print_art(int* a, int len){
for(int i=0; i<len; i++){
printf("%d ", a[i]);
}
}
//插入排序
void insert_sort(int* a, int len){
int temp;//保存待插元素
int j;//循环变量
//插入排序三步走:
//1.从第二个元素开始往前插入
//2.找到满足条件的插入点并且将元素后移
//3.将此处a[j]与temp存储的待插元素交换
//1.从第二个元素开始往前插入
for(int i=1; i<len; i++){
temp = a[i];//保存待插元素
j = i - 1;
//2.找到满足条件的插入点并且将元素后移
while(j>=0 && a[j]>temp){
a[j+1] = a[j]; //赋值
j--;
}
//3.将此处a[j]与temp存储的待插元素交换
a[j+1] = temp;
}
}
//shell排序
void shell_sort(int* a, int len){
//shell排序三步走:
int step = len / 2;//1.初始化步长
int temp;
int j;
while(step >= 1){//2.每次步长都要减半
//3.组内插入排序
for(int i=step; i<len; i++){//注意i=step,从步数step那里开始向后
temp = a[i];
j = i - step;//每次减少一次步长
while(j>=0 && a[j]>temp){
a[j+step] = a[j]; //赋值
j = j-step;//元素后移
}
a[j+step] = temp;
}
step = step/2;//步长减一
}
}
//主函数测试
int main(){
int a[NUM] = {1, 22, 5, 8, 88, 16, 66, 20, 30, 666};
insert_sort(a, NUM);
print_art(a, NUM);
shell_sort(a, NUM);
print_art(a, NUM);
return 0;
}
2.基数排序:
# include<iostream>
# include<vector>
#define NUM 10
using namespace std;
void print_art(int* a, int len){
for(int i=0; i<len; i++){
printf("%d ", a[i]);
}
}
//基数排序
void radix_sort(int* a, int len, int max){
//基数排序5步走:
// 1.创建临时数组
// 2.初始化临时数组
// 3.临时数组排序
// 4.将临时数组值赋值回原数组
// 5.delete临时数组
int* b = new int[max+1];//创建临时数组
int j = 0;
for(int i=0; i<max+1; i++)//初始化临时数组
b[i] = -1;
for(int i=0; i<len; i++)//临时数组排序
b[a[i]] = a[i];
for(int i=0; i<max+1; i++){//将临时数组值赋值回原数组
if(b[i] != -1){
a[j++] = b[i];
}
}
delete[] b;//删除
}
int main(){
int a[NUM] = {1, 22, 5, 8, 88, 16, 66, 20, 30, 666};
radix_sort(a, NUM, 666);
print_art(a, NUM);
return 0;
}
3.桶排序:
# include<iostream>
# include<vector>
# include<string.h>
//元素个数
#define NUM 10
//数据范围限定:3位数(小于1000)
#define AREA 1000
void print_art(int* a, int len){
for(int i=0; i<len; i++){
printf("%d ", a[i]);
}
}
//桶排序
void bucket_sort(int* a, int len){
//桶排序
// 1.根据数据范围获取排序次数
// 2.制作桶并且初始化
// 3.遍历a数组并且按照排序依据将a数组元素存到桶里
// 4.放回原来数组里
for(int i=1; i<AREA; i*=10){//根据数据范围获取排序次数:三位数则排序次数为3次(个位,十位,百位)
int temp[10][NUM];//制作桶
memset(temp, -1, sizeof(int)*10*NUM);//桶初始化每个元素为-1
for(int j=0; j<len; j++){
int m = a[j] / i % 10;//取到所需要的位
temp[m][j] = a[j];//将取到的位存到对应桶里
}
int k = 0;//放回原来数组里
for(int p=0; p<10; p++){
for(int q=0; q<NUM; q++){
if(temp[p][q] != -1){
a[k++] = temp[p][q];
}
}
}
}
}
int main(){
int a[NUM] = {1, 22, 5, 8, 88, 16, 66, 20, 30, 666};
bucket_sort(a, NUM);
print_art(a, NUM);
return 0;
}

浙公网安备 33010602011771号