数据结构-----折半插入排序

自我意识的多元宇宙 2026-04-28 22:48:44

一、基本思想

折半插入排序是直接插入排序的优化版本。直接插入排序在向前找插入位置时,采用顺序查找,比较次数多、效率低;由于前面的有序区始终有序,因此可以用 折半查找(二分查找) 快速定位插入位置。
核心:
划分有序区、无序区,和直接插入排序一致;
利用二分,快速算出待插入元素应该放的下标;
统一批量后移元素,再放入目标值;
只减少比较次数,元素移动次数不变。


二、算法执行步骤

初始:数组第 0 号元素为有序区,从 i=1开始遍历无序区;取出当前待插入元素 temp = a[i];在有序区间 [0, i−1] 内,用折半查找找到插入位置 low;将插入位置到 i−1 的所有元素整体向后移动一位;将 temp 放入空位,完成一趟插入;重复直到全部有序。


三、完整 C 语言代码

#include <stdio.h>

// 折半插入排序
void BinaryInsertSort(int a[], int n)
{
    int i, low, high, mid;
    int temp;

    // 无序区从第2个元素开始
    for (i = 1; i < n; i++)
    {
        temp = a[i];        // 暂存待插入元素
        low = 0;
        high = i - 1;       // 划定有序区范围

        // 1.折半查找插入位置
        while (low <= high)
        {
            mid = (low + high) / 2;
            if (temp < a[mid])
                high = mid - 1;
            else
                low = mid + 1;
        }
        // 循环结束:low 即为插入位置

        // 2.元素统一后移,腾出位置
        for (int j = i - 1; j >= low; j--)
        {
            a[j + 1] = a[j];
        }

        // 3.插入元素
        a[low] = temp;
    }
}

// 打印数组
void Print(int a[], int n)
{
    for (int i = 0; i < n; i++)
        printf("%d ", a[i]);
    printf("\n");
}

int main()
{
    int arr[] = {49, 38, 65, 97, 76, 13, 27};
    int len = sizeof(arr) / sizeof(arr[0]);
    BinaryInsertSort(arr, len);
    Print(arr, len);
    return 0;
}

四、代码逐行详细解析

for(i = 1; i < n; i++)i 指向无序区第一个元素,有序区为 [0,i−1]。
temp = a[i]保存待插入数值,防止后移覆盖丢失。
low = 0 , high = i - 1限定二分查找范围:整个前面的有序区间。
二分核心循环
temp < a[mid]:目标值更小,去左半区间,high = mid - 1
temp >= a[mid]:去右半区间,low = mid + 1
循环结束时,low 就是唯一正确插入下标。
for(j = i-1; j >= low; j--)从后往前,把插入位置后面所有元素集体后移一位。
a[low] = temp空位填入待插入元素,本趟排序完成。


五、性能分析

时间复杂度
比较次数:由 O(n 2 ) 优化为 O(nlog 2 n)
元素移动次数:仍为 O(n 2 )
整体平均、最坏时间复杂度:O(n 2 )
空间复杂度仅常数辅助变量:O(1),就地排序
稳定性稳定排序相等元素不会交换相对位置。


六、折半插入 vs 直接插入

相同点
都属于插入排序;
稳定、原地排序;
最坏 / 平均时间复杂度 O(n 2 )。
不同点
直接插入:顺序找位置,比较多、效率低;
折半插入:二分找位置,大幅减少比较次数,适合数据量稍大的有序类序列。

...全文
81 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

151

社区成员

发帖
与我相关
我的任务
社区描述
这里专为新疆政法学院的探索者而建,英雄不问出处。起跑线是起点,热忱与坚持为加速器,无论bug缠身的项目,还是攻克的算法顿悟,每滴汗水皆被珍藏。执炬前行,终将照亮彼此峰顶,我们携手同行。
课程设计笔记经验分享 高校 新疆·图木舒克市
社区管理员
  • 雲中203
  • SHAO060706
  • 三叶草.
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

英雄不问出处

试试用AI创作助手写篇文章吧