二分插入排序(Binary Insertion Sort)
过程图示:
1.a[0]--a[3]已经是有序表
2.left
和 right
用来确定目标插入位置。left
是最小的可能插入位置,right
是最大的可能插入位置。通过不断调整这两个边界,最终可以找到合适的插入位置。
mid=(left+right)/2
3. 7>5(a[mid]),left=mid+1,mid=(left+right)/2
4. 7<10(a[mid]),right=mid-1
5. right<left,将待插入元素插入left位置
在代码中我们认为第一个元素为有序列表,从第二个元素开始遍历。
简易代码描述:
void Binsert_sort(int a[], int n)
{
int i, j, left, right, mid, x;
for (i = 1; i < n; i++)
{
x = a[i];
left = 0;
right = i - 1;
// 使用二分查找确定插入位置
while (left <= right)
{
mid = (left + right) / 2;
if (x < a[mid])
{
right = mid - 1;
}
else
{
left = mid + 1;
}
}
// 右移动元素以为新元素腾出位置
for (j = i - 1; j >= left; j--)
{
a[j + 1] = a[j];
}
// 将新元素插入到正确的位置
a[left] = x;
}
}
代码分析:
-
二分查找部分:
- 这部分代码通过二分查找确定了插入位置
left
。 - 当
x < a[mid]
时,将右边界right
移到mid - 1
,否则将左边界left
移到mid + 1
。
- 这部分代码通过二分查找确定了插入位置
-
移动元素:
- 在找到插入位置后,需要将从
left
到i-1
的所有元素右移,以为新元素x
腾出位置。
- 在找到插入位置后,需要将从
-
插入元素:
- 在完成元素的移动后,将
x
插入到正确的位置a[left]
。
- 在完成元素的移动后,将