首页 > 代码库 > (经典)直接插入排序based on 二分查找

(经典)直接插入排序based on 二分查找

#include<stdio.h>
// 查找第一个大于key的元素,成功则返回该元素的下标,否则返回数组末元素的下一位
int findFirstLarger(int A[],int n, int key)
{
    int left = 0;
    int right = n-1;

    // 这里必须是 <=
    while (left <= right) {
        int mid = (left + right) / 2;
        if (A[mid] > key) {
            right = mid - 1;
        }
        else {
            left = mid + 1;
        }
    }
    return left;
}

void insert(int a[],int n)
{   int flag,temp,j,i,k;

    //3个元素要进行2趟排序
    for(j=1;j<n;j++){  //对位序1,2,3....n分别进行插入,bug隐藏在这,应该是1,2,3,n-1

        //对[0,j-1]进行插入排序,将j指向的元素插入
        flag = findFirstLarger(a,j,a[j]);

        if(flag ==j) continue ;
        temp = a[j]; //保存将要插入的元素
        //将i(flag待插入的那个位置)之后的元素后移动一位
        for(k=j;k>flag;k--){
            a[k]=a[k-1];
        }
        //将temp插入到i这个位置
        a[flag] = temp;

    }

}


int main()
{   int tt;
    int a[] = {1,90,90,4,4,4,9,9,10,20,20,-1010,222,666};
    insert(a,14);
    for(tt=0;tt<14;tt++){
        printf("%d\n",a[tt]);
    }
    return 0;
}

典型错误:

//顺序查找第一个比key大的元素

int position1(int a[],int n,int key)//传入有序表和要查找的元素位置
{
    int i;
    for(i=0;i<n;i++){
        if(a[i]>key)  return i; //这样做就不行了
    }
    return i+1;
}

//这个才是正确的
int position(int a[],int n,int key)//传入有序表和要查找的元素位置
{
    int i,index=-1;
    for(i=0;i<n;i++){
        if(a[i]>key)  index = i ; break; //从前往后是大于符号
    }
    if(index == -1)
        return n;
    else return index;
}

 

(经典)直接插入排序based on 二分查找