简单算法之插入排序及其优化shell排序
来源:互联网 发布:java语言培训哪家好 编辑:程序博客网 时间:2024/06/06 01:44
1>插入排序:顾名思义是通过不断把新的元素插入到前面有序的序列中。
思路:1.当数组只有一个元素时,不需要排序。所以插入排序从a[1]开始;
2.当数组长度为n时,那么所要插入的元素a[1]~a[n-1],这利用for循环遍历所有需要被插入的元素
3.当a[i]小于a[i-1],那么a[i]就需要往前插入,以使得a[0-i]数组有序,而且a[i]是有可能小于
i-2,i-3,….,0,所以要一直往前比较插入。那么就必须把a[i]存放在一个临时变量中,这相当于在
在a[i]上挖了一个坑(快速排序中就利用了这种方法:挖坑),不断的把前面有序的元素往后移,直到刚好比a[i]大的元素,移了一位,留下了一个坑,最后把存放在临时变量里的原a[i]存放进去。就实现了
a[0-i]有序。
这是在一本书上看到的排序代码void InsertSort(int a[],int len){ for(int i=1;i<len;i++){ if(a[i]<a[i-1]){ //如果后面的数小于前面的数,那就需要插入 int temp=a[i]; //挖坑 for(int j=i-1;j>=0 && a[j]>temp;j--) a[j+1]=a[j]; a[j+1]=temp; } }}我觉得这个方法不是很好,一开始我看了半天,没理解。下面是我自己写的
void InsertSort1(int a[],int len){ for(int i=1;i<len;i++){ int temp=key; //依旧是挖坑。 int j=i; while(j-1>=0 && key<arr[j-1]){ arr[j]=arr[j-1]; //依次往前填坑,并形成新的坑 j--; } arr[j]=temp; //填上最后一个坑 }}对比于上面的代码,我少了一个if的判断,但是我觉得那个判断是多余的,因为后面的循环中你还是会判断一遍。可能那样效率高一点,但是对于总体的时间复杂度来说,应该没多大区别。希望有大神指导一下。
2>插入排序的时间复杂度是o(n^2),既要比较又要移动,但是如果数组本身是有序的那么他的时间复杂度为
o(n),只需要遍历一遍数组就好了。所以基于以上,我们要尽量在数组有序的时候使用插入排序。而shell排序正是居于以上思想提出的对插入排序的一种优化排序算法。
shell排序:通过把序列按一定增量分成若干个子序列,并对每个子序列进行插入排序。
一般这个增量是n/2,元素为n个。
原理是这样的:例如一个数组
12,11,3,25,2,13 按照增量6/2来划分,分成三组
12 25
11 2
3 13
再按照增量3/2划分,分成一组,那么就直接进行插入排序。
代码实现如下public void ShellSort(){ int[] arr={12,11,3,25,2,13,17,4,19,2}; for(int gap=arr.length/2;gap>0;gap/=2){ //改变增量,直至增量为1 for(int i=0;i<gap;i++){ //根据增量分成了多少组 for(int j=i+gap;j<arr.length;j+=gap){ //对每一组进行插入排序 int temp=arr[j]; while(j-gap>0 && arr[j-gap]>temp){ arr[j]=arr[j-gap]; j-=gap; ] arr[j]=temp; } } }}//要逻辑清楚,第一步要改变增量。第二步要遍历根据增量分成的每一个组。第三步要对每一组进行插入排序。这里不再是向前移一位比较了,而是向前移gap个位置来比较。
shell排序之所以效率高,是因为把数组分成了多个序列,开始进行插入排序的组数虽然多,但元素少,后面进行插入排序元素多,但已经快要趋近于有序了。所以这样比直接用插入排序效率要高很多。
- 简单算法之插入排序及其优化shell排序
- 经典算法之Shell排序及其优化
- 排序算法之选择和插入排序的简单优化
- 经典算法之直接插入排序及其优化
- 排序算法之插入排序及其改进
- 排序算法之 插入排序、希尔(shell)排序 及其时间复杂度和空间复杂度
- 插入排序及其优化
- 插入排序及其优化
- 插入排序及其优化
- 插入排序及其优化
- 排序算法之冒泡排序及其优化
- 冒泡排序算法及其简单优化算法
- 内部排序算法之简单插入排序
- C++简单排序算法之插入排序
- 排序算法之简单插入排序法
- Java排序算法之简单插入排序
- 排序算法之简单插入排序
- 插入排序优化:简单插入排序->二分查找插入排序->二路插入排序->shell插入排序
- CodeForces 474EPillars(线断树区间最大)
- 300. Longest Increasing Subsequence
- RC522读卡器 M1卡学习总结(二)
- NOIP2015普及组 金币
- JDBC--使用statement接口实现更新数据
- 简单算法之插入排序及其优化shell排序
- Go语言基础:并发
- makefile
- http://www.cnblogs.com/spring87/p/4496930.html
- linux和windows的进程的虚拟地址空间
- 第四周项目4-建设双链表算法库
- Linux管道pipe -- C和Python两种实现方案解析
- 树链剖分模板
- USB的包结构及包分类