算法复习——插入排序

原理都很清楚:

i从1到n-1遍历,将a_i插入到之前已经排序好的子序列[a_0, a_1, ..., a_{i-1}]中,用二分法找到插入的位置。

看起来很简单,但是实现的时候,也需要思考一些细节。

二分法的插入排序关键在于插入位置的下标。

void insertsort(int *arr, int n){
/* arr: array, n: size of arr*/
    int s, t, mid;
    for(int i=1; i<n; i++){
        s = 0;
        t = i;
        while(s < t){
            mid = (s + t) / 2;
            if(arr[i] < arr[mid]){
                t = mid;
            } else if(arr[i] >= arr[mid]){
                s = mid + 1;
            }
        }
//insert arr[i] to index t
        int tmp = arr[i];
        for(int j=i; j>t; j--){
            arr[j] = arr[j-1];
        }
        arr[t] = tmp;
    }
}

其中, s为头指针,t为尾指针。s选择指向子序列的第一个元素,t指向最后一个元素的下一个位置(很重要)

对于一个子序列a_0, a_1, ..., a_{i-1},所有有可能的插入位置有i+1个。也就是每两个元素之间(i-1个)加上序列的头和尾。

 

所以,我们需要一个指针的值域也是有i+1个值。t正好满足了这个需求。由于t \in [0, i],所以可以用t为基准,作为元素的插入点,这也是为什么t需要是指向子序列的最后一个元素的下一个位置。如果t指向的是子序列的最后一个元素,则t \in [0, i-1],值域只有i个值。那么,当子序列的所有值都小于a_i的时候,a_i无法插入到子序列的末尾处。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值