目录

折半插入排序原理

折半插入排序图文说明

代码实现

C实现

JAVA实现

复杂度分析和稳定性

复杂度

稳定性

总结


折半插入排序原理

折半插入排序是对直接插入排序的一种改良方式,在直接插入排序中,每次向已排序序列中插入元素时,都要去寻找插入元素的合适位置,但是这个过程是从已排序序列的最后开始逐一去比较大小的,这其实很是浪费,因为每比较一次紧接着就是元素的移动。折半排序就是通过折半的方式去找到合适的位置,然后一次性进行移动,为插入的元素腾出位置。什么是折半的方式去找合适的位置呢,那就是折半查找了,因为再已排序的序列中,序列元素都是按照顺序排列的,既然这样,完全不需要逐一去比较大小,而是去比较已排序序列的中位数,这个中间的位置将一排序列分为左右两部分,通过一次比较后,就缩小了比较的范围,重复这样的操作,需要插入的元素就找到了合适的位置了。

折半插入排序图文说明

注:蓝色代表已排序序列,白色代表未排序序列,红色箭头指向未排序序列的第一个元素位置。

如图所示,现在有一个待排序序列[8 5 4 2 3],首先默认初始状态下,位置0的数字8作为已排序序列[8],位置1--位置4的[5 4 2 3 1] 为待排序序列,之后就逐一从[5 4 2 3 1]中取出数字向前进行比较,插入到已排序序列的合适位置。寻找过程中将蓝色的已排序区域不断进行折半。

初始状态下,已排序区只有一个数据元素8,low位置和high位置都指向了该位置,mid为中间位置,此时很显然也是0位(0+0)/ 2。此时temp < mid,将high指向mid的前一位,这里也就是-1,这个时候high=-1low=1,很显然high<low,每当这个时候,就到了移动元素的时候了,将(high+1)(i-1)的元素都向后移一位,再把(high+1)位置上插入要插入的元素。

之后的操作也是这样类似的,详细过程如下图。

代码实现

C实现

代码:

#include <stdio.h>void insertSort(int array[], int n){int temp;for(int i = 1; i < n; i++){int low = 0;int hight = i-1;temp = array[i];while(hight>=low){int mid = ( low + hight ) / 2;if (array[mid] > temp){hight = mid - 1;}else{low = mid + 1;}}for (int j = i-1; j > hight; j--) {array[j+1] = array[j];}array[hight+1] = temp;}
}void main(){int i;int a[8] = { 8, 5, 4, 3, 2, 1, 6, 7 };printf("before:{");for(i = 0; i < 8; i++){printf("%d ",a[i]);}printf("}\n");insertSort(a,8);printf("after:{");for(i = 0; i < 8; i++){printf("%d ",a[i]);}printf("}\n");}

测试结果:

JAVA实现

代码:

/*** Created by GFC on 2018/8/29.*/
public class HalfSearchSort {public void sort(int[] array){int temp;for(int i = 1; i < array.length; i++){int low = 0;int hight = i-1;temp = array[i];while(hight>=low){int mid = ( low + hight ) / 2;if (array[mid] > temp){hight = mid - 1;}else{low = mid + 1;}}for (int j = i-1; j > hight; j--) {array[j+1] = array[j];}array[hight+1] = temp;}}public static void main(String[] args) {HalfSearchSort sort = new HalfSearchSort();int a[] = {8, 5, 4, 3, 2, 1, 6, 7};System.out.println("Before: " + Arrays.toString(a));//System.out.println(5/2);sort.sort(a);System.out.println("After: " + Arrays.toString(a));}
}

测试结果

复杂度分析和稳定性

复杂度

和直接插入排序相比较,折半插入排序仅仅是减少了比较的次数,而移动总次数并没有发生改变。这个比较次数大概是,移动次数没有改变,所以其复杂度和直接插入排序是一样的

稳定性

根据代码分析可以知道,当待插入数与mid位置的值相等时,接下来相当于进入了有序序列的右半区,mid+1到high,之后经过多次折半查找,该元素所找到的合适位置就是前一个与之相等元素的后一位,所以说两者相对位置没有发生变化,这般插入排序是稳定的。

总结

折半插入排序其实是在直接插入排序的基础上,结合了二分查找法的思想,顺序的二分查找替代了直接插入排序中遍历查找的过程,从而更快的能够确定待插入元素的位置,但是由于移动次数并没有发生改变,所以两者的时间复杂度相同。折半插入排序是稳定的,其时间复杂度为

【排序】折半插入排序相关推荐

  1. 算法不会,尚能饭否之排序——折半插入排序(Binary Insert Sort)

    还是排序,上一篇讲的是排序大家庭中的直接插入排序,今天呢,主要讲的是折半插入排 序.实现起来,还是蛮简单的,没有太多的拐弯抹角的,不会伤害很多脑细胞的.人家都 说了,编程,如何提高自己的编程技术呢?那 ...

  2. 【排序】插入类排序—(折半)插入排序、希尔排序

    前言 在数据结构和算法中,排序是非常重要的一环,并且排序也是渗透编程的方方面面. 你或许在写一个sql的order by按照某组进行排序,又或者你在刷一道题时候.常常遇到贪心+自定义排序求解的思路题, ...

  3. 排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序...

    先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎 ...

  4. 直接插入排序,折半插入排序,希尔排序,简单选择排序,冒泡排序,快速排序模板以及比较次数与移动次数的分析,折半搜索算法模板

    #include<stdio.h> #include<time.h> #include <stdlib.h>const int maxx=1e2+1; int a[ ...

  5. 经典排序算法(4)——折半插入排序算法详解

    折半插入排序(Binary Insertion Sort)是一种插入排序算法,通过不断地将数据元素插入到合适的位置进行排序,在寻找插入点时采用了折半查找. 一.算法基本思想 (1)基本思想 折半插入排 ...

  6. 数据结构与算法系列——排序(3)_折半插入排序

    1. 工作原理(定义) 二分插入排序(Binary Insertion Sort,折半插入排序 OR 拆半插入排序),采用折半查找方法. 二分查找插入排序的原理:是直接插入排序的一个变种:区别是:在有 ...

  7. 排序算法(一)--插入排序法折半插入排序法

    约定: 假设数据中有n个数据元素(关键字).排列算法中,将序列中各关键字值依次存放于类型为keytype的数组元素K[1], K[2], K[3], -, K[n]中. 排序结果按照数据元素(关键字) ...

  8. 排序算法第二篇——折半插入排序

    算法描述: 在上一篇插入排序算法中,已经提到,插入排序的核心是在有序的集合中找到要插入的位置.所以,在这里介绍一种对插入排序的改进算法,即折半插入排序.折半插入排序是指利用折半查找的算法,在有序集合中 ...

  9. java 快速排序算法简单_排序算法java版,速度排行:冒泡排序、简单选择排序、直接插入排序、折半插入排序、希尔排序、堆排序、归并排序、快速排序......

    先推荐一篇关于排序算法的文章:http://www.cppblog.com/guogangj/archive/2009/11/13/100876.html 本文思路部分来源于上篇文章,但测得的结果似乎 ...

  10. 王道八大排序:直接插入排序 折半插入排序 希尔排序 冒泡排序 快速排序 归并排序 基数排序

    文章目录 1.插入排序 1.1直接插入排序 1.2折半插入排序 1.3希尔排序 2.交换排序 2.1冒泡排序 2.2快速排序 3.选择排序 3.1简单选择排序 3.2堆排序 4.归并排序 5.基数排序 ...

最新文章

  1. 1051 Pop Sequence(两种双指针思路)
  2. 如何在Python中将一个字符串附加到另一个字符串?
  3. Condition总结-CountDownLatch源码分析
  4. TrackFormer解读
  5. 单片机小白学步系列(七) 准备实验板——萝卜青菜,各有所爱
  6. PHP进程退出信号_一文吃透 PHP 进程信号处理
  7. java private 对象_[Java笔记]类的所有构造器都是private权限,就一定没有办法实例化它的对象了么?...
  8. python换行输出三个数中最大数_关于Python 3中print函数的换行详解
  9. python print rdd_spark: RDD与DataFrame之间的相互转换方法
  10. 软件工程预测模型之COCOMO
  11. 【最新】半小时教你制作出属于自己的QQ机器人【保姆级】
  12. 七牛云 转码_七牛云视频在线转码 - 持久化处理
  13. NLP会议介绍 2019
  14. 推广有哪些渠道?用好这4个引流渠道日引200
  15. 计算机在职英语,我是社会在职人员,能考什么样的英语?
  16. 007-系统主要界面
  17. 最新版SwitchHosts下载安装教程
  18. 电子信息计算机科学方向考研,专业是电子信息科学与技术,考研该考什么学
  19. 一次windows server 2003系统修复过程
  20. OpenCV学习+常用函数记录①:图像的基本处理

热门文章

  1. android录音波浪动画_Android使用音频信息绘制动态波纹
  2. 文件 服务器属性,去除服务器文件上的RHS属性
  3. 嵌入式实时操作系统4——任务调度
  4. python入门的小问题:计算复利函数
  5. Linux下设置火狐主页的方法
  6. 一支笔的测试点_如何测试一支笔
  7. R语言线性判别分析(LDA),二次判别分析(QDA)和正则判别分析(RDA)
  8. 服务器常见错误代码500、501、502、503、504、505
  9. foxmail发生RCPT错误
  10. nyoj 81 迷宫寻宝