文章目录
折半插入排序(Binary Insertion Sort)是插入排序的一种优化版本,通过二分查找确定插入位置,减少了比较次数,从而提升排序效率。
1. 算法步骤
1、初始状态:将数组分为已排序部分(初始为第一个元素)和未排序部分。
2、遍历未排序部分:
对当前元素 key,在已排序部分中使用二分查找确定插入位置 pos。
将 pos 之后的元素向后移动一位,腾出空间。
将 key 插入到 pos 位置。
3、重复:直到所有元素处理完毕。
2. 代码实现
以下代码通过二分查找寻找到需要插入的位置,在返回需要插入的位置后,移动数组。
c
#include <stdio.h>
// 二分查找函数:在已排序数组arr[low..high]中找到key的插入位置
int binary_search(int arr[], int key, int low, int high) {
while (low <= high) {
int mid = low + (high - low) / 2;
if (arr[mid] == key) {
return mid; // 找到相等元素,返回其位置
}
if (arr[mid] < key) {
low = mid + 1;
} else {
high = mid - 1;
}
}
return low; // 未找到时返回第一个大于key的位置
}
// 折半插入排序函数
void binary_insertion_sort(int arr[], int n) {
for (int i = 1; i < n; i++) {
int key = arr[i];
int pos = binary_search(arr, key, 0, i - 1); // 在已排序部分查找插入位置
// 移动元素:从pos到i-1的元素向后移动一位
for (int j = i - 1; j >= pos; j--) {
arr[j + 1] = arr[j];
}
arr[pos] = key; // 插入key到正确位置
}
}
int main() {
int arr[] = {37, 23, 0, 17, 12, 72, 31};
int n = sizeof(arr) / sizeof(arr[0]);
printf("原始数组: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
binary_insertion_sort(arr, n);
printf("排序后数组: ");
for (int i = 0; i < n; i++) {
printf("%d ", arr[i]);
}
printf("\n");
return 0;
}
4. 优缺点
4.1、优点:
1、减少比较次数,对大规模数据比普通插入排序更快。
2、稳定且原地排序。
4.2、缺点:
1、移动次数未优化。
2、对随机数据效率不如更高级的排序(如快速排序、归并排序)。