从二分查找到折半插入排序

Posted goodswarm

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了从二分查找到折半插入排序相关的知识,希望对你有一定的参考价值。

从二分查找到折半插入排序

回忆直接插入排序的过程,发现每趟排序中进行了两个动作:

1. 从左边的已排序序列中找寻插入位置。

2. 给插入位置腾出空间,将插入元素复制到表中的插入位置。

步骤一在直接插入排序中是一个“Linear Search”顺序查找过程,而我们知道二分查找比顺序查找更优秀

折半插入排序性能

  • Space Complexity: S(n)=O(1)
  • Time Complexity: T(n)=O((n^2))
  • 一种稳定的排序

因为折半排序仅仅减少了比较元素的次数,约为(O(nlog_2n)),而移动次数并未改变。折半插入排序的复杂度仍为(O(n^2))

Code

code 1 (选取自GeeksforGeeks)结构清晰

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);
}

void insertionSort(int arr[], 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;
    }
}

code 2(教材版本改)

int i, key, j, low, high, mid;

for (i = 1; i < n; ++i)
{
    key = a[i];     //保存待排序元素的值
    j = i - 1;          //从待排序元素的前一个开始
    //二分查找部分
    low = 0;
    high = j;
    
    while (low <= high)
    {
        mid = low + (high - low) / 2;
        if (a[mid] > key)
            high =  mid - 1;
        else low = mid + 1;     //小于或者等于low为mid右位置
    }
    // Move all elements after location to create space
    while (j >= low)
    {
        a[j+1] = a[j];
        --j;
    }
    a[j+1] = key;
}

以上是关于从二分查找到折半插入排序的主要内容,如果未能解决你的问题,请参考以下文章

经典排序算法 – 插入排序Insertion sort

排序之折半插入排序

经典排序算法——折半插入排序

直接插入排序 ,折半插入排序 ,简单选择排序, 希尔排序 ,冒泡排序 ,快速排序 ,堆排序 ,归并排序的图示以及代码,十分清楚

Java实现折半(二分)插入排序

插入排序——2折半插入排序实现