插入二分排序

一、STL版本的插入二分排序

#include <bits/stdc++.h>
using namespace std;

const int N = 6;
int a[N] = {3, 2, 1, 4, 5, 7};

void BinInsertSort(int a[], int n) {
    for (int i = 1; i < n; i++) { // 把下标0的没处理,做为基础数据,其它的一个个做二分插入排序
        int x = a[i];             // 辅助变量x用来保存待排序的元素,因为后面有整体移动的过程,不单独记下来,后面就被改了
        // 这个代码其实很巧妙的,一个数组分两半用,一半是待插入的,另一个是插入完的,牛啊!
        int pos = lower_bound(a, a + i, x) - a;             // 在a数组中,范围[0,a+i)这个前闭后开的区间内查找第一个大于等于x的位置p
        for (int j = i - 1; j >= pos; j--) a[j + 1] = a[j]; // 移动元素,腾出空间,将pos位置倒出来
        a[pos] = x;                                         // 将待排序的元素插入
    }
}

int main() {
    // 插入排序+二分
    BinInsertSort(a, N);
    for (int i = 0; i < N; i++) printf("%d ", a[i]);
    return 0;
}

二、手写二分版本的插入二分排序

#include <bits/stdc++.h>
using namespace std;

const int N = 6;
int a[N] = {3, 2, 1, 4, 4, 7};

void BinInsertSort(int a[], int n) {
    for (int i = 1; i < n; i++) { // 把下标0的没处理,做为基础数据,其它的一个个做二分插入排序
        int x = a[i];             // 辅助变量x用来保存待排序的元素,因为后面有整体移动的过程,不单独记下来,后面就被改了
        // 这个代码其实很巧妙的,一个数组分两半用,一半是待插入的,另一个是插入完的,牛啊!

        // 手写二分lower_bound模板,左闭右开
        int l = 0, r = i; //[0~i-1] <=> [0,i)
        while (l < r) {
            int mid = (l + r) >> 1;
            if (a[mid] >= x)
                r = mid;
            else
                l = mid + 1;
        }
        // 此处写l,r都是一样的
        for (int j = i - 1; j >= r; j--) a[j + 1] = a[j]; // 移动元素,腾出空间,将pos位置倒出来
        a[r] = x;                                         // 将待排序的元素插入
    }
}

int main() {
    // 插入排序+二分
    BinInsertSort(a, N);
    for (int i = 0; i < N; i++) printf("%d ", a[i]);
    return 0;
}
posted @   糖豆爸爸  阅读(36)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!
历史上的今天:
2020-02-20 Postgresql主从流复制+Redis集群部署
2020-02-20 数据仓库实时数据同步方案
2016-02-20 关于云平台的统计分析通用方案
2012-02-20 Varnish加速网站图片显示
Live2D
点击右上角即可分享
微信分享提示