《算法二》(希尔排序+基数排序+桶排序)
排序算法: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; }