折半插入排序

直接插入排序

import java.util.Arrays;

public class 直接插入排序
{
    public static void main(String[] args)
    {
        int[] disorderedArr = { 4, 3, 6, 2, 5, 16, 12, 9, 7 };
        insertionSort(disorderedArr);
        System.out.println(Arrays.toString(disorderedArr));
    }

    // 直接插入排序
    // 输入:整型数组
    // 副作用:对输入数组进行非降序排列
    private static void insertionSort(int[] arr)
    {
        int len = arr.length;
        int value = 0;

        // 认为第一个数已经排好了,据此从第二个数开始为之后的数查找插入位置
        for (int i = 1; i < len; ++i)
        {
            value = arr[i];
            // 第i个数之前的数已经排好序了,此处逆序进行元素比较,可以充分利用这一情况,当待插入数大于某一个数时,就不用再将该数和前面的数比了
            int j = i - 1; // 0 ~ j 内的数已排序
            for (; j >= 0 && arr[j] > value; --j)
            {
                arr[j + 1] = arr[j];
            }
            arr[j + 1] = value; // value插入的位置只比j表示的位置大一个
        }
    }
}

空间复杂度: O(1)
时间复杂度: O(n2)

二分查找

// 折半查找
public class 折半查找
{
    public static void main(String[] args)
    {
        // TODO Auto-generated method stub
        int[] arr = { 1, 3, 6, 9 };
        int result = binarySearch(arr, 9);
        System.out.println("index=" + result + " value="
                + (result == -1 ? "Not Found" : arr[result]));
    }

    private static int binarySearch(int[] arr, int key)
    {
        int l = 0, r = arr.length - 1;

        while (l <= r)
        {
            int mid = (l + r) / 2;
            if (key == arr[mid])
                return mid;
            else if (key > arr[mid])
                l = mid + 1;
            else
                r = mid - 1;
        }

        return -1;
    }
}

空间复杂度: O(1)
时间复杂度: O(lgn)

折半插入排序

import java.util.Arrays;

public class 折半插入排序
{
    public static void main(String[] args)
    {
        int[] disorderedArr = { 4, 3, 6, 2, 5, 16, 12, 9 };
        insertionSortByBinarySearch(disorderedArr);
        System.out.println(Arrays.toString(disorderedArr));
    }

    // 折半插入排序
    // 输入:整型数组
    // 副作用:对输入数组进行非降序排列
    private static void insertionSortByBinarySearch(int[] arr)
    {
        int len = arr.length;
        int value = 0;

        // 认为第一个数已经排好了,据此从第二个数开始为之后的数查找插入位置
        for (int i = 1; i < len; ++i)
        {
            value = arr[i];
            int l = 0;
            int r = i - 1; // 前i个数有序
            int posi = binarySearch(l, r, arr, value);
            for (int j = i; j > posi; --j)
            {
                arr[j] = arr[j - 1];
            }
            arr[posi] = value;
        }
    }

    private static int binarySearch(int l, int r, int[] arr, int value)
    {
        while (l <= r)
        {
            int mid = (l + r) / 2;
            if (value == arr[mid])
                return mid;
            else if (value > arr[mid])
                l = mid + 1;
            else
                r = mid - 1;
        }

        return l;
    }
}

空间复杂度: O(1)
时间复杂度: O(n2)
由于移动元素的复杂度依旧为 O(n2) ,所以折半插入排序的时间复杂度依旧为 O(n2)

你可能感兴趣的:(基本算法)