二分应用的小坑———折半插入排序

啊!啊!啊!啊!啊!!!

TLE越界了

太久没有写代码了

虽热很久没有写代码和博客了,但是功底还是在的
今天打算写一点数据结构的排序部分一点一点落实下来,但是
写着写着卡壳了,以下是没有debug的代码

#include <iostream>
#include<bits/stdc++.h>

using namespace std;
vector<int> a;

int check(int l, int r, int x) {
    while (l < r) {
        int mid = (l + r + 1) >> 1;
        if (a[mid] > x) {
            r = mid - 1;
        } else {
            l = mid;
        }
    }
    return r;
}

void mid_insert_sort() {
    for (int i = 1; i < a.size(); i++) {
        int x = check(0, i, a[i]);
        cout << x << ' ' << i << endl;
        for (int j = i; j > x; j--) {
            swap(a[j], a[j - 1]);
        }
        for (int j = 0; j < a.size(); j++) {
            cout << a[j] << ' ';
        }
        cout << endl;
    }
}

int main() {
    int n;
    cin >> n;
    while (n--) {
        int x;
        cin >> x;
        a.push_back(x);
    }
    mid_insert_sort();
    for (int i: a)cout << i << ' ';
}



反正二分和折半插入的思想没有错
然后开始慢慢检查二分check函数的错误
1.check函数用的bool函数写的
然后返回值都是01,,,,,
以后尽量不用bool类型了,妈的
找完了之后
debug好久硬是没有错误

然后挑了一个例子debug发现每一次

10
49 59 88 37 98 97 68 54 31 3


1 1
49 59 88 37 98 97 68 54 31 3 
2 2
49 59 88 37 98 97 68 54 31 3 
0 3
37 49 59 88 98 97 68 54 31 3 
4 4
37 49 59 88 98 97 68 54 31 3 
3 5
37 49 59 97 88 98 68 54 31 3 
2 6
37 49 68 59 97 88 98 54 31 3 
1 7
37 54 49 68 59 97 88 98 31 3 
0 8
31 37 54 49 68 59 97 88 98 3 
0 9
3 31 37 54 49 68 59 97 88 98 
3 31 37 54 49 68 59 97 88 98 

发现了一个问题

当x大于当前队伍的所有值时,还是会交换x
然后我就特判了一下,发现还是错误,于是我就单独的把check函数拉出来检查一下,发现一个大问题,二分的范围是有限的
就比如这题: 1-5,我的check函数是找到小于等于x的最大值
我发现如果所有值都小于x那么函数return就会返回1
但是这是错误的
然会我就发现,,,,,二分是在当前的范围内进行查找,,,,
但是插入在范围中会比原来的范围多两个边界值
所以,,,,,加上a[0]就可以了,,,,,

#include <iostream>
#include<bits/stdc++.h>

using namespace std;
const int N = 1e5 + 100;
int a[N];
int n;


int check(int l, int r, int x) {
    while (l < r) {
        int mid = (l + r + 1) >> 1;
        if (a[mid] > x) {
            r = mid - 1;
        } else {
            l = mid;
        }
    }
    return r;
}

void mid_insert_sort() {
    for (int i = 1; i <= n; i++) {
        int x = check(0, i, a[i]);
        int idx = i;
        for (int j = i; j - 1 > x; --j) {
            swap(a[j], a[j - 1]);
        }

    }

}

int main() {
    a[0] = INT32_MAX;
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> a[i];
    }
    mid_insert_sort();
    for (int i = 1; i <= n; i++)cout << a[i] << ' ';
}

~~大意了,,,,这么个简单的代码和思想
,,,,之前一直以为哨兵是没有用的
在这里插入图片描述

主要是之前的习惯比较好,会特意注意边界问题,一般不会越界,
但是这个插入的会在边界值多出,,,,所以没有想到~~

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值