📜  二进制插入排序

📅  最后修改于: 2021-05-04 15:21:13             🧑  作者: Mango

我们可以使用二进制搜索来减少普通插入排序中的比较次数。二进制插入排序使用二进制搜索来找到正确的位置,以便在每次迭代时插入所选项目。
在普通插入排序中,在最坏的情况下需要进行O(n)个比较(第n次迭代)。我们可以使用二进制搜索将其简化为O(log n)。

C++
// C program for implementation of
// binary insertion sort
#include 
 
// A binary search based function
// to find the position
// where item should be inserted
// in a[low..high]
int binarySearch(int a[], int item,
                 int low, int high)
{
    if (high <= low)
        return (item > a[low]) ?
                (low + 1) : low;
 
    int mid = (low + high) / 2;
 
    if (item == a[mid])
        return mid + 1;
 
    if (item > a[mid])
        return binarySearch(a, item,
                            mid + 1, high);
    return binarySearch(a, item, low,
                        mid - 1);
}
 
// Function to sort an array a[] of size 'n'
void insertionSort(int a[], int n)
{
    int i, loc, j, k, selected;
 
    for (i = 1; i < n; ++i)
    {
        j = i - 1;
        selected = a[i];
 
        // find location where selected sould be inseretd
        loc = binarySearch(a, selected, 0, j);
 
        // Move all elements after location to create space
        while (j >= loc)
        {
            a[j + 1] = a[j];
            j--;
        }
        a[j + 1] = selected;
    }
}
 
// Driver Code
int main()
{
    int a[]
        = { 37, 23, 0, 17, 12, 72, 31, 46, 100, 88, 54 };
    int n = sizeof(a) / sizeof(a[0]), i;
 
    insertionSort(a, n);
 
    printf("Sorted array: \n");
    for (i = 0; i < n; i++)
        printf("%d ", a[i]);
 
    return 0;
}


Java
// Java Program implementing
// binary insertion sort
 
import java.util.Arrays;
class GFG
{
   
    public static void main(String[] args)
    {
        final int[] arr = { 37, 23, 0,   17, 12, 72,
                            31, 46, 100, 88, 54 };
 
        new GFG().sort(arr);
 
        for (int i = 0; i < arr.length; i++)
            System.out.print(arr[i] + " ");
    }
 
    // Driver Code
    public void sort(int array[])
    {
        for (int i = 1; i < array.length; i++)
        {
            int x = array[i];
 
            // Find location to insert
            // using binary search
            int j = Math.abs(
                Arrays.binarySearch(array, 0,
                                    i, x) + 1);
 
            // Shifting array to one
            // location right
            System.arraycopy(array, j,
                             array, j + 1, i - j);
 
            // Placing element at its
            // correct location
            array[j] = x;
        }
    }
}
 
// Code contributed by Mohit Gupta_OMG


Python
# Python Program implementation
# of binary insertion sort
 
 
def binary_search(arr, val, start, end):
     
    # we need to distinugish whether we
    # should insert before or after the
    # left boundary. imagine [0] is the last
    # step of the binary search and we need
    # to decide where to insert -1
    if start == end:
        if arr[start] > val:
            return start
        else:
            return start+1
 
    # this occurs if we are moving
    # beyond left's boundary meaning
    # the left boundary is the least
    # position to find a number greater than val
    if start > end:
        return start
 
    mid = (start+end)//2
    if arr[mid] < val:
        return binary_search(arr, val, mid+1, end)
    elif arr[mid] > val:
        return binary_search(arr, val, start, mid-1)
    else:
        return mid
 
 
def insertion_sort(arr):
    for i in range(1, len(arr)):
        val = arr[i]
        j = binary_search(arr, val, 0, i-1)
        arr = arr[:j] + [val] + arr[j:i] + arr[i+1:]
    return arr
 
 
print("Sorted array:")
print(insertion_sort([37, 23, 0, 31, 22, 17, 12, 72, 31, 46, 100, 88, 54]))
 
# Code contributed by Mohit Gupta_OMG


C#
// C# Program implementing
// binary insertion sort
using System;
 
class GFG {
 
    public static void Main()
    {
        int[] arr = { 37, 23, 0,   17, 12, 72,
                      31, 46, 100, 88, 54 };
 
        sort(arr);
 
        for (int i = 0; i < arr.Length; i++)
            Console.Write(arr[i] + " ");
    }
 
    // Driver Code
    public static void sort(int[] array)
    {
        for (int i = 1; i < array.Length; i++)
        {
            int x = array[i];
 
            // Find location to insert using
            // binary search
            int j = Math.Abs(
                Array.BinarySearch(array,
                                   0, i, x) + 1);
 
            // Shifting array to one location right
            System.Array.Copy(array, j,
                              array, j + 1,
                              i - j);
 
            // Placing element at its correct
            // location
            array[j] = x;
        }
    }
}
 
// This code is contributed by nitin mittal.


PHP
 $a[$low]) ?
                       ($low + 1) : $low;
 
    $mid = (int)(($low + $high) / 2);
 
    if($item == $a[$mid])
        return $mid + 1;
 
    if($item > $a[$mid])
        return binarySearch($a, $item,
                            $mid + 1, $high);
         
    return binarySearch($a, $item, $low,
                            $mid - 1);
}
 
// Function to sort an array a of size 'n'
function insertionSort(&$a, $n)
{
    $i; $loc; $j; $k; $selected;
 
    for ($i = 1; $i < $n; ++$i)
    {
        $j = $i - 1;
        $selected = $a[$i];
 
        // find location where selected
        // item should be inserted
        $loc = binarySearch($a, $selected, 0, $j);
 
        // Move all elements after location
        // to create space
        while ($j >= $loc)
        {
            $a[$j + 1] = $a[$j];
            $j--;
        }
        $a[$j + 1] = $selected;
    }
}
 
// Driver Code
$a = array(37, 23, 0, 17, 12, 72,
           31, 46, 100, 88, 54);
            
$n = sizeof($a);
 
insertionSort($a, $n);
 
echo "Sorted array:\n";
for ($i = 0; $i < $n; $i++)
    echo "$a[$i] ";
 
// This code is contributed by
// Adesh Singh
?>


输出
Sorted array: 
0 12 17 23 31 37 46 54 72 88 100

时间复杂度:由于每次插入都需要进行一系列交换,因此整个算法在最坏情况下的运行时间仍为O(n 2 )。