1. 程式人生 > >4.圖解-折半插入排序 Binary insert sort

4.圖解-折半插入排序 Binary insert sort

1. 思想

  折半插入排序是對直接插入排序的改進。 直接插入排序就是不斷的依次將元素插入前面已經排好序的序列中。
  由於前半部分為已經排好的序列,這樣就不用按順序依次比較尋找插入點,而是採用折半查詢的方法來加快尋找插入點

2.圖解-折半查詢

 

  將關鍵字 7 折半查詢插入到 numbersArray。 查詢過程如上圖


int[] numbersArray = {1,3,4,6,7,8,10,13,14,18,19,21,24,37,40,45,71};

//第 1 次
low = 0
high = 16
middle = (0+16)/2 = 16/2 = 8
7 (target at index 4) < 14 (middle at index 8)
high = middle - 1 = 7

//第 2 次
low = 0
high = 7
middle = (0+7)/2 = 7/2 = 3 R 1
7 (target at index 4) > 6 (middle at index 3)
low = middle + 1 = 4

//第 3 次
low = 4
high = 7
middle = (4+7)/2 = 11/2 = 5 R 1
7 (target at index 4) < 8 (middle at index 5)
high = middle - 1 = 4

//第 4 次
low = 4
high = 4
middle = (4+4)/2 = 8/2 = 4
7 (target at index 4) == 7 (middle at index 4)

3.Code in Java

import java.util.Arrays;

class BinaryInsertionSort {

	public static void main(String[] args) {
		final int[] input = {4, 10, 3, 1, 9, 15, 40, 45, 71 };
		System.out.println("Before Sorting - " + Arrays.toString(input));
		new BinaryInsertionSort().sort(input);
		System.out.println("After Sorting - " + Arrays.toString(input));
	}

	private static void sort(int[] dataArr) {
		for (int i = 1; i < dataArr.length; i++) {
			int temp = dataArr[i];
			int low = 0, high = i - 1;
			while (low <= high) {
				int mid = (low + high) / 2;
				if (temp < dataArr[mid]) {
					high = mid - 1;
				} else {
					low = mid + 1;
				}
			}
			int j = i - 1;
			for (; j >= high + 1; j--) {
				dataArr[j + 1] = dataArr[j];
			}
			dataArr[j + 1] = temp;
		}
	}



}

Code in C

#include <stdio.h>
#include <stdlib.h>



// A binary search based function to find the position
// where item should be inserted
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 program to test above function
int main()
{
    int a[] = {1, 18, 19, 21, 24, 37, 3, 4, 16, 7, 8, 10, 13, 40, 45};
    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;
}

 

 

 

4.演算法分析

  與直接排序比較:減少了關鍵字比較的次數,但記錄移動的次數沒有變,時間複雜度是 N²

排序類別

排序方法

時間複雜度

空間複雜度

穩定性

複雜性

平均情況

最壞情況

最好情況

插入排序

折半插入排序

O(N²)

O(N²)

O(N²)

O(1)

穩定

簡單

5.參考

 

https://en.wikipedia.org/wiki/Binary_search_algorithm