二分法插入排序算法的尝试

Posted

tags:

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

  这是一个《算法导论》上的练习,可将插入排序的总体运行时间降至Θ(nlgn),我们先看看插入排序的算法代码:

#include <stdio.h>

int main(void)
{
    int arr[] = {6,3,1,5,4,2};
    int i, j;
    int temp;

    for(i = 1; i < sizeof(arr)/sizeof(int); i++)    //运行时间Θ(n)
    {
        temp = arr[i];
        j = i - 1;
        while(j >= 0 && arr[j] > temp)        //这里线性时间进行查找移动,运行时间Θ(n),所以整体运行时间Θ(n^2)
        {
            arr[j + 1] = arr[j];
            j--;
        }
        arr[j + 1] = temp;
    }

    for(i = 0; i < sizeof(arr)/sizeof(int); i++)
        printf("%d ", arr[i]);
    printf("\n");
    return 0;
}

  从代码可以看出,arr[j] > temp的判断查找是在前面所有小于 j 的部分中进行移动和查找的,而小于的 j 部分都是已经排好序的,因此我们可设计使用二分查找带进行更快速的处理。但我的尝试出现了问题:

/**
 *  二分法+插入排序 - Θ(nlgn)
 *
 */
#include <stdio.h>

int main(void)
{
    int arr[] = {6,3,1,5,4,2};
    int i, j;
    int mid, left;
    int temp;

    left = 0;
    for(i = 1; i < sizeof(arr)/sizeof(int); i++)
    {
        temp = arr[i];
        j = i - 1;
        mid = (left + j) / 2;
        while(temp > arr[mid + 1] || temp < arr[mid - 1])        
     //情况是这样的,比如:进行到 123645,当把4进行比较后,从1236中查找位置时
     //只有当同时不满足循环条件,即 3 < 4 < 6 时,不满足条件 ,就可以退出了,当前的 mid 就是4可以插入的位置。
{ if(arr[mid] > temp) mid = (mid + j) / 2; else if(arr[mid] < temp) mid = (left + mid) / 2; } for(j = i - 1; j >= mid; j--){    //移动要插入的位置以后且小于当前比较数以前的位置 arr[j + 1] = arr[j]; } arr[j] = temp;    //把比较数插入其中 } for(i = 0; i < sizeof(arr)/sizeof(int); i++) printf("%d ", arr[i]); printf("\n"); return 0; }

  然而,我的尝试失败了,代码看上去好像没什么问题,但while还是陷入了死循环,不知道什么原因...这个循环条件的判断难道有什么问题吗?我暂时先记录下来吧,改天再继续思考这个问题...

以上是关于二分法插入排序算法的尝试的主要内容,如果未能解决你的问题,请参考以下文章

算法之希尔排序快速排序二分查找

带你整理面试过程中常考的九大排序算法

排序算法(冒泡,选择,插入,快速)查找算法(二分,快速)

Java八股文面试题 基础篇 -- 二分查找算法冒泡排序选择排序插入排序希尔排序快速排序

Java八股文面试题 基础篇 -- 二分查找算法冒泡排序选择排序插入排序希尔排序快速排序

排序算法之二分法(折半)插入排序算法