二分法排序

算法思想简单描述:

在插入第i个元素时,对前面的0~i-1元素进行折半,先跟他们 中间的那个元素比,

如果小,则对前半再进行折半,否则对后半 进行折半,直到left>right,

然后再把第i个元素前1位与目标位置之间 的所有元素后移,再把第i个元素放在目标位置上。

二分法排序最重要的一个步骤就是查找要插入元素的位置,

也就是要在哪一个位置上放我们要准备排序的这个元素。

当我们查找到位置以后就很好说了,和插入排序一样,

将这个位置以后的所有元素都向后移动一位。这样就实现了二分法排序。

然后是怎么查找着一个位置呢,就是不断的比较已排序的序列中的中间元素和要排序元素,

如果中间元素大于要排序元素的话,说明这个要排序的元素在已排序序列中点之前的序列。

public static void DichotomySort(int[] array)
{
  for (int i = 0; i < array.Length; i++)
  {
    int start, end, mid;
    start = 0;
    end = i - 1;
    mid = 0;
    int temp = array[i];
    while (start <= end)
    {
      mid = (start + end) / 2;
      if (array[mid] > temp) //要排序元素在已经排过序的数组前半部分
      {
        end = mid - 1;
      }
      else                   // 要排序元素在已经排序的数组后半部分
      {
        start = mid + 1;
      }
    }
    for (int j = i - 1; j > end; j--) //找到了要插入的位置,然后将这个位置以后的所有元素向后移动
    {
      array[j + 1] = array[j];
    }
    array[end + 1] = temp;
  }
}

二分插入排序实际上是对插入排序的优化。

(1)算法思想

根据插入排序的思想,在插入待排序列的第i个元素时,由于前面的序列已经有序,因此可以使用二分法寻找第i个元素的正确位置。

(2)伪代码:

BinInsertSort( int a[ ], int n )
{
  int key, left, right, middle;
  for ( int i = 1; i < n; i++ )
  {
    key = a[ i ];
    left = 0;
    right = i - 1;
    while ( left <= right )
    {
      middle = ( left + right ) / 2;
      if ( a[ middle ] > key )
        right = middle - 1;
      else
        left = middle + 1;
    }

    for ( int j = i - 1; j >= left; j-- )
    {
      a[ j + 1 ] = a[ j ];
    }

    a[ left ] = key;
  }
}

折半插入排序其实就是直接插入排序的一种改进,引入了二分查找算法,这样关键字的比较次数就会减少,

数量级为O(nlog^2n),但是元素移动次数还是O(n^2),所以折半插入排序的时间复杂度是O(n^2)。

另外,折半插入排序是稳定的排序算法;下面是用JAVA写的算法的两种实现方式。不过原理都是一样的

import java.util.Arrays;

public class BinarySearch1
{
  public static void main(String args[])
  {
    int array[]=
    { 49,38,65,97,76,13,27};
    binarySort(array,array.length);
    System.out.println("---------排序后的结果----------");
    System.out.println(Arrays.toString(array));
  }

  //二分查找
  public static int binarySearch(int array[],int low,int high,int temp)
  {
    int mid=0;
    while(low<=high)
    {
      mid=(low+high)/2;
      if(array[mid]<temp&&temp<=array[mid+1])
      return (mid+1);
      else if(array[mid]<temp)
      low = mid + 1;
      else
      high = mid -1;
    }
    return high;
  }

  //二分排序
  public static void binarySort(int array[],int size)
  {
    int i,j,k,temp;
    for(i=1;i<size;i++)
    {
      temp=array[i];
      if(array[i]<array[0])
      k=0;
      else
      k = binarySearch(array,0,i,temp);

      for(j=i;j>k;j--)
      {
        array[j]=array[j-1];
      }
      array[k]=temp;
      System.out.println(Arrays.toString(array));
    }
  }
} 
[38, 49, 65, 97, 76, 13, 27]
[38, 49, 65, 97, 76, 13, 27]
[38, 49, 65, 76, 97, 13, 27]
[13, 38, 49, 65, 76, 97, 27]
[13, 27, 38, 49, 65, 76, 97]
---------排序后的结果----------
[13, 27, 38, 49, 65, 76, 97]
package sort;

import java.util.Arrays;

public class BinarySearch2
{
  public static void main(String args[])
  {
    int array[]=
    { 49,38,65,97,76,13,27};
    binaryInsertSort(array,array.length);
    System.out.println("------------排序后的结果-------------");
    System.out.println(Arrays.toString(array));
  }

  /**
   *
   * @param array 要排序的数组
   * @param size 数组的大小
   */
  public static void binaryInsertSort(int []array,int size)
  {
    int i,j,temp;
    int low,high,mid;
    for(i=1;i<size;i++)
    {
      //将待插入的元素赋给temp,这个元素前面是有序数组,用于插入到有序数组中
      temp=array[i];
      low=0;
      high=i-1;
      while(low<=high)
      {
        //有序数组的中间坐标,此时用于二分查找,减少查找次数
        mid = (low+high)/2;
        //如果有序序列中的中间元素大于待排序的元素,则有序序列的中间坐标向前搜索,否则向后搜索
        if(array[mid]>array[i])
        high=mid-1;
        else
        low = mid + 1;
      }
      /**
       * j首先赋值为要插入值的前一个元素的最后的坐标,也就是有序数组中最后一个元素的坐标
       * 然后依次向前扫描有序数组,然后如果满足条件则向后移动数据
       */

      for(j=i-1;j>=low;j--)
      {
        array[j+1]=array[j];
      }
      //将待排序的元素插入到array数组中
      array[low]=temp;
      System.out.println(Arrays.toString(array));
    }
  }
} 
[38, 49, 65, 97, 76, 13, 27]
[38, 49, 65, 97, 76, 13, 27]
[38, 49, 65, 97, 76, 13, 27]
[38, 49, 65, 76, 97, 13, 27]
[13, 38, 49, 65, 76, 97, 27]
[13, 27, 38, 49, 65, 76, 97]
------------排序后的结果-------------
[13, 27, 38, 49, 65, 76, 97]
时间: 2024-12-23 17:11:49

二分法排序的相关文章

分享一个多线程实现[冒泡][选择][二分法]排序的例子

线程的使用规则我将会在我另一篇文章<Delphi中使用比较少的一些语法>中进行介绍,这里只开放一篇Delphi原代码的算法: //工程文件:Sort_MultiThread.dpr program Sort_MultiThread; uses  Forms,  SortUI in 'SortUI.pas' {fmSortUI},  SortUC in 'SortUC.pas'; {$R *.res} begin  Application.Initialize;  Application.Mai

js 排序:sort()方法、冒泡排序、二分法排序。

js中的排序,这里介绍三种,sort()方法.冒泡排序.二分法排序. 1.sort方法 写法:  数组.sort(); 返回排好序的数组,如果数组里是数字,则由小到大,如果是字符串,就按照第一个字符的字符编码大小排序. 写法2: 数组.sort(function(a,b){ return a-b }); 表示从大到小,(如果写 retrun b-a 则由大到小排序): 不详细解释了. 2.冒泡排序. 原理是,直接将原理可能不好懂,我们还是按照下面的方法去讲吧,这样容易懂些. //冒泡排序func

Java中的几种排序算法:冒泡排序,插入排序,二分法排序,简单排序,快速排序

冒泡排序: int[] hehe={4,7,2,5,6,9,0}; for(int i=0;i<hehe.length;i++){ for(int j=i+1;j<hehe.length;j++){ if(hehe[i]>hehe[j]){ int temp=hehe[i]; hehe[i]=hehe[j]; hehe[j]=temp; } } } 插入排序 int[] a={13,7,8,9,10,1,2,32}; int i,j,t,h; for (i=1;i<a.length

JAVA学习笔记-二分法排序(增强for循环)

package MyErFenPaiXu; public class Mycode { public static void main(String[] args){ int[] a ={18,63,25,46,3,0,99,1,2}; for(int j=0;j<a.length-1;j++){ //这里的意思为不断的比较,次数只要不小于5次就能遍历出想要的结果. for(int i=0;i<a.length-1-j;i++){ //遍历一次,一个大数会被移到最后的位置. if(a[i]&g

Java排序查找算法——二分法与递归的应用实例

问题描述: 对数组元素进行查找与排序,利用二分法与递归实现. 完整实例1: public class SortDemo {    public static void main(String[] args)    {       int[] arr={10,2,300,41,15,6};       for(int a:arr)       {          System.out.print("["+a+"]");           }      // new

Java中常见的排序算法

这是我摘取的一段英文资料,我觉得学习算法之前,对各种排序得有个大致的了解: Sorting algorithms are an important part of managing data. At Cprogramming.com, we offer tutorials for understanding the most important and common sorting techniques. Each algorithm has particular strengths and w

二分法简介

老规矩: 什么是二分法: 其实是一个数学领域的词,但是在计算机领域也有广泛的使用. 为什么需要二分法? 当穷举算法性能让你崩溃时. 二分法怎么用呢? 让我们先玩一个游戏先,我心里想一个100以内的整数你来猜猜.那么你可以从1-100这么猜,当然如果我说我想的10000以内的,那么迭代次数线性上升...你懂的      当然你可以先设一个猜想数,我们可以采用2分之一的方法猜,首先是50 那么比50大的化就在50-100取2分之一为猜想数,继续.当然2分法不一定是2分之一,只是取决 于答案出现的区间

冒泡法、选择法、插入法、二分法

小序 排序是非常重要且很常用的一种操作,有冒泡排序.选择排序.插入排序.希尔排序.快速排序.堆排序等多种方法.这里我们先简单介绍前三种排序算法和代码的实现,其余算法将在后续课程<数据结构>中学习到.算法只是一种思想,其实现依赖于数据结构,所以这里提取出一些典型的算法和数据结构,包括排序以及链表/堆栈/队列等结构的操作. ------------------------------------------------------ 冒泡法排序 数组中有N个整数,用冒泡法将他们从小到大(或从大到小)

Java中的七种排序方式代码示例

package baseJava; /** * @title SortMethods.java * @author DonsenChen * @Date 2018年5月2日 上午10:16:03 * @Description */ public class SortMethods { public static void main(String[] args) { int[] arr = { 3, 7, 9, 1, 4, 8, 2, 6, 5 }; binarySort(arr); bubble