折半插入排序

记得之前总结过插入排序,有兴趣的可以看看---插入排序

   如果在最复杂的情况下,所要排序的整个数列是逆序的,当第 i-1 趟需要将 第 i 个元素插入前面的 0~ i -1 个元素的序列当中的时候,它总是会从第 i -1 个元素开始,逐个比较每个元素的大小,直到找到相应的位置。

   这个算法中丝毫没有考虑当要插入第 i 个元素时前面的 0~~ i -1 序列是有序的这个特点。今天要总结的这个算法就充分的利用了这一点。

 

算法的基本过程:

   1)计算 0 ~ i-1 的中间点,用 i 索引处的元素与中间值进行比较,如果 i 索引处的元素大,说明要插入的这个元素应该在中间值和刚加入i索引之间,反之,就是在刚开始的位置 到中间值的位置,这样很简单的完成了折半;

   2)在相应的半个范围里面找插入的位置时,不断的用(1)步骤缩小范围,不停的折半,范围依次缩小为 1/2  1/4  1/8 .......快速的确定出第 i  个元素要插在什么地方;

   3)确定位置之后,将整个序列后移,并将元素插入到相应位置。

 

算法实现:

import java.util.*;

public class BinaryInsertSort {
    private static int[] Sort(int[] arr) {
        int i, j;
        //保存中间插入的值
        int insertNote = 0;
        //将待排序的数列保存起来
        int[] array = arr;
        System.out.println("开始排序:");
        for (i = 1; i < array.length; i++) {
            int low = 0;
            int high = i - 1;
            insertNote = array[i];
            //不断的折半
            while (low <= high) {
                //找出中间值
                int mid = (low + high) / 2;
                //如果大于中间值
                if (array[i] > array[mid]) {
                    //在大于中间值的那部分查找
                    low = mid+1;
                } else
                    //在小于中间值的那部分查找
                    high = mid-1;
            }
          //将整体数组向后移
            for ( j=i; j > low; j--) {
                array[j] = array[j - 1];
            }
         //插入到指定的位置
            array[low] = insertNote;
            System.out.println(Arrays.toString(array));
        }
        System.out.println("排序之后:");
        System.out.println(Arrays.toString(array));
        return array;
    }

    public static void main(String[] args) {
        Random random = new Random();
        int[] array = new int[10];
        for (int i = 0; i < 10; i++) {
            array[i] = Math.abs(random.nextInt() % 100);
        }
        System.out.println("排序之前:");
        System.out.println(Arrays.toString(array));
        BinaryInsertSort.Sort(array);
    }
}

 

 输出截图:

算法分析:

   1)时间复杂度:

   折半插入排序比直接插入排序明显减少了关键字之间的比较次数,但是移动次数是没有改变。所以,折半插入排序和插入排序的时间复杂度相同都是O(N^2),在减少了比较次数方面它确实相当优秀,所以该算法仍然比直接插入排序好。

   2)空间复杂度:

   折半插入排序和插入排序一样只需要一个多余的缓存数据单元来放第 i 个元素,所以空间复杂度是O(1),因为排序前2个相等的数在序列的前后位置顺序和排序后它们两个的前后位置顺序相同,所以它是一个稳定排序。 

 

作者:Orson 
出处:http://www.cnblogs.com/java-class/ 
如果,您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】 
如果,您希望更容易地发现我的新博客,不妨点击一下左下角的【关注我】 
如果,您对我的博客内容感兴趣,请继续关注我的后续博客,我是【Orson】 

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段 声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。 

转载:http://www.cnblogs.com/java-class/archive/2013/06/01/3112461.html

时间: 2024-09-25 04:18:55

折半插入排序的相关文章

Java实现直接插入排序和折半插入排序算法示例_java

直接插入排序​1 排序思想: 将待排序的记录Ri插入到已经排好序的记录R1,R2,--,R(N-1)中. 对于一个随机序列而言,就是从第二个元素开始,依次将这个元素插入到它之前的元素中的相应位置.它之前的元素已经排好序. 第1次排序:将第2个元素插入到前边的有序列表(此时前边只有一个元素,当然是有序的),之后,这个序列的前2个元素就是有序的了. 第2次排序:将第3个元素插入到前边长度为2的有序列表,使得前2个元素是有序的. 以此类推,直到将第N个元素插入到前面长度为(N-1)的有序列表中. 2

常见的五类排序算法图解和实现(插入类:直接插入排序,折半插入排序,希尔排序)

基本的五类排序算法(插入,选择,交换,归并,基数排序).排序:将数据元素的一个任意序列,重新排列成一个按关键字有序的序列. 排序的稳定性:待排序列中有大于等于2个相同的项,且排序前后,相同项的相对位置是否发生了变化(如果变化了就是不稳定的排序,不变化就是稳定的) 内部排序:若整个排序过程不需要访问外存便能完成,则称此类排序问题为内部排序:(待排序列全部放入内存) 插入累排序:(直接插入,折半插入,希尔排序) 直接插入排序: 先将序列中第 1 个记录看成是一个有序子序列, 然后从第 2 个记录开始

asp.net中C++插入排序 折半插入排序法例子

C++插入排序 包括折半插入排序法代码,在直接插入排序,数组data用于存放待排序元素,n为待排序元素个数,同时还包括了对data数组中的元素进行希尔排序,n为该数组大小等:    代码如下 复制代码 #include <iostream> using namespace std; #include "sort.h" // 直接插入排序,数组data用于存放待排序元素,n为待排序元素个数 template<class ElemType> void InsertS

浅析直接插入排序与折半插入排序_C 语言

首先看一下例子,将数据一个个的插入到一个列表中,插入后这个列表就排序好了 注意:这个列表是递增的,而且内存空间已分配好,只是没有填充真正的数据,如下代码: 复制代码 代码如下: int InsertSort(MergeType *L, int data){ int j;  if (!L->len) {  L->elem[++L->len] = data;  return 0; }  for (j = L->len-1; j >= 0; --j) {  if (data <

JS折半插入排序算法实例_javascript技巧

本文实例讲述了JS折半插入排序算法.分享给大家供大家参考,具体如下: function pushArrayWithIndex(arr, index, value) { // 将元素添加到数组的指定位置 var temArr = arr.slice(0, index); temArr.push(value); return temArr.concat(arr.slice(index)); } /* test for pushArrayWithIndex var arr = [1, 2, 3, 4,

排序算法之折半插入排序

折半插入排序     在直接插入排序的基础上做的改进,直接插入排序在寻找插入位置时是从后到前依次比较,直到找到插入位置.而折半插入排序在寻找插入位置时,先与有序序列中的中间位置R[mid]进行比较,如果比中间位置上的记录大,则在R[mid+1-N]中寻找,继续与右区间的中间记录进行比较:如果比中间位置上的记录小,则在R[0-mid-1]中寻找,继续与左区间中的数据进行比较. typedef int datatype; int BinaryInsertionSort(datatype *array

折半查找(binary search) 算法示例

折半查找, 又称二分查找(binary search), 需要数组有序(sort), 通过比较数组的中间数据(中心偏向较小的方法), 确定查找值的范围; 直到中值等于查找值, 则查找成功; 如果未成功, 则重置数据, 判断首尾位置的大小, 再进行中值比较; 判断失败, 则数据不存在; 注意: 1. Eclipse无法重定向(redirect)输入文件(file), 只能读入数据; 2. 使用cmd重定向输入文件, 则需要解压"stdlib.jar", 取出相应的class(In, Ou

内部排序:插入排序和希尔排序的N种实现

前言 本来想将所有的内部排序总结为一篇博文,但是随着研究的深入,还是放弃了这个念头,斟前酌后,还是觉得分开来写比较好,具体原因,看完本篇博文也就自然明了了. 本篇文章主要探讨插入排序和希尔排序,之所将二者放在一起,很明显,是因为希尔排序是建立在插入排序的基础之上的. 注:以下各排序算法的N种实现方法大部分都是我根据算法思想,自己写出来的,或者是参考其本身的经典实现,我自己都已测试通过,但不敢保证一定都没问题,如果有疑问,欢迎指出. 插入排序 插入排序的思想很简单,它的基本操作就是将一个数据插入到

数据结构教程 第三十四课 插入排序、快速排序

教学目的: 掌握排序的基本概念,插入排序.快速排序的算法 教学重点: 插入排序.快速排序的算法 教学难点: 快速排序算法 授课内容: 一.排序概述 排序:将一个数据元素的无序序列重新排列成一个按关键字有序的序列. 姓名 年龄 体重 1李由 57 62 2王天 54 76 3七大 24 75 4张强 24 72 5陈华 24 53 上表按年龄无序,如果按关键字年龄用某方法排序后得到下表: 姓名 年龄 体重 3七大 24 75 4张强 24 72 5陈华 24 53 2王天 54 76 1李由 57