算法排序(2):插入排序
来源:互联网 发布:mac 照片 导出 编辑:程序博客网 时间:2024/06/05 22:31
插入排序有直接插入排序和希尔排序俩种,我们分别来看:
一、直接插入排序
直接插入排序的原理是将数据分为已排序和待排序俩部分,每次从待排序部分获取一个数据,从已排序的部分找到适合位置插入,直到待排序的数据全部取完。
稳定性:稳定
时间复杂度:最好O(N),平均O(N2), 最坏O(N2)
空间复杂度:O(1)
举个栗子:
需要排序的数据为:4 8 3 6 1
1.先将4作为已经排序部分,8 3 6 1 为待排序部分
2.从待排序部分取出8,插入到已经排序的部分中
3.插入后已排序结果为4 8,整体为 4 8 3 6 1(黑体为已经排好的部分)
4.继续以上操作,取出3插入3 4 8 6 1
5.取出6插入3 4 6 8 1
6.取出1插入1 3 4 6 8
待排序取完数据后,可以得到结果,数据已经全部排好序了。
在插入数据时,为了插入到合适的位置,可能要移动已排好的数据,从而时间复杂度会比较高,也就是说,直接插入排序适合数据量较少,而且比较有序的数据排序。
接下来用代码实现:
void insertsort(int arr[],int len){ int tmp=0; int j=0; for(int i=1;i<len;i++) { tmp=arr[i]; j=i-1; while(j>=0&&arr[j]>tmp) { arr[j+1]=arr[j]; j--; } arr[j+1]=tmp; }}
二、希尔排序
希尔排序是直接插入排序的升级,用来弥补直接插入排序适合数据量少的缺点。
算法思想是确定一个增量组合,通过增量来划分大数据,每一次划分好数据,对划分的数据分别进行直接插入排序(数据较为无序,但是数据量大大减少),直到最后的增量为一(此时数据已经较为有序),进行最后一次直接插入排序。
稳定性:稳定
时间复杂度:最好O(N),平均O(N1.3), 最坏O(N2)
空间复杂度:O(1)
接下来用代码实现:
void shell(int arr[],int arr_len,int dk) //一次SHELL{ int tmp,j; for(int i=dk;i<arr_len;i++) { tmp=arr[i]; j=i-dk; while(j>=0&&arr[j]>tmp) { arr[j+dk]=arr[j]; j-=dk; } arr[j+dk]=tmp; }}void shellsort(int arr[],int arr_len,int dka[],int dka_len) //希尔排序总控制{ for(int i=0;i<dka_len ;i++) { shell(arr,arr_len,dka[i]); }}
由于希尔排序不稳定,我们来做一点修改,让它变得稳定。我的一个简单思路是,首先将待排序数组预处理,将重复的数据筛选出来,直到无重复数据部分进行最后一次希尔排序,重复数据参与这最后一次希尔排序,即转化为一次直接插入排序,我们知道直接插入排序是稳定的,所以本次希尔排序也稳定。
代码如下:
int init(int arr[],int arr_len,int *brr,int *crr){ int i=1; int j=1; int k=0; int key=0; brr[0]=arr[0]; for(i;i<arr_len ;i++) { key=k; for(int p=0;p<j;p++) { if(brr[p]==arr[i]) { crr[k]=arr[i]; k++; break; } } if(key==k) { brr[j]=arr[i]; j++; } } return k;}void shell(int arr[],int arr_len,int dk){ int tmp,j; for(int i=dk;i<arr_len;i++) { tmp=arr[i]; j=i-dk; while(j>=0&&arr[j]>tmp) { arr[j+dk]=arr[j]; j-=dk; } arr[j+dk]=tmp; }}void show(int arr[],int len){ for(int i=0;i<len;i++) { printf("%d ",arr[i]); } printf("\n");}void shellsort(int arr[],int arr_len,int dka[],int dka_len,int *brr,int *crr){ int crrlen=init(arr,arr_len,brr,crr); for(int i=0;i<dka_len-1 ;i++) { shell(brr,arr_len-crrlen,dka[i]); } int j=0; for(j;j<arr_len-crrlen;j++) { arr[j]=brr[j]; } for(int k=0;k<crrlen;k++) { arr[j]=crr[k]; j++; } show(arr,arr_len); shell(arr,arr_len,1);}
- 经典排序算法2(插入排序)
- 排序算法(2)-直接插入排序
- 算法排序(2):插入排序
- 算法学习之排序算法:插入排序(直接插入排序、折半插入排序、2-路插入排序)
- 排序算法2-插入排序
- 排序算法(2)----插入排序
- 排序:插入排序(算法)
- 算法---插入排序(直接插入排序)
- 排序算法-插入排序
- 排序算法--插入排序
- 排序算法---插入排序
- 排序算法-插入排序
- 排序算法-插入排序
- 排序算法--插入排序
- 排序算法-插入排序
- 排序算法-插入排序
- 排序算法---插入排序
- 排序算法--插入排序
- HashMap中的indexFor方法分析
- 用jDB 调试Java程序
- Spring2.5的新特性:第一部分
- hadoop JOB的性能优化实践
- zoj 2112 (主席树,树状数组套线段树)
- 算法排序(2):插入排序
- MySql命令行
- JavaScript框架之AngularJS学习——双向数据绑定
- hadoop分布式平台优化
- ccf 游戏 bfs
- 分清tcp/ip与http
- sql中having和where的区别
- 树形菜单构造
- 蚁群算法路径规划TSP