码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2019-10-16 11:19:07      阅读:104      评论:0      收藏:0      [点我收藏+]

标签:toc   str   href   geeks   div   空间   for   span   move   

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

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

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

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

标签:toc   str   href   geeks   div   空间   for   span   move   

原文地址:https://www.cnblogs.com/goodswarm/p/11684144.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!