我搜索出来的2-路插入排序结果是一个折半排序
或者2-路直接插入排序
以下和书中的排序方式一样
#include<iostream>
#include<vector>
#include<iomanip>
using std::vector;
void print(const vector<int> &ivec)
{
using namespace std;
cout << left;
for (auto x : ivec)
cout << setw(4) << x;
cout << endl;
}
//二路折半排序
void insertSort(vector<int> & ivec)
{
int length = ivec.size();
vector<int> copy(length);
copy[0] = ivec[0]; //copy[0]==ivec[0] 排序完成前是不会动的
int first = 0; //当前最小元素位置
int final = 0; //当前最大元素位置
for (int i = 1; i < length; i++)
{
int temp = ivec[i];
// 在copy[0]的右侧
if (temp >= ivec[0]) //将相等情况归于右侧保证稳定性
{
int low = 0;
int high = final;
while (low <= high)
{
int mid = (low + high) / 2;
if (temp >= copy[mid])
low = mid + 1;
else
high = mid - 1;
}
//右移
for (int j = final; j > high; j--)
copy[j + 1] = copy[j];
copy[high + 1] = temp;
final++;
}
else
{
int low = first;
int high = 0;
while(low <= high)
{
int mid = (low + high) / 2;
if (temp >= copy[(mid + length) % length])
low = mid + 1;
else
high = mid - 1;
}
//左移
for (int j = first; j <= high; j++)
copy[length + j - 1] = copy[length + j];
copy[high + length] = temp;
first--;
}
print(copy);
}
//copy首位依然是ivec[0],将有序数组放入ivec中
ivec.assign(copy.begin() + final + 1, copy.end());
ivec.insert(ivec.end(), copy.begin(), copy.begin() + final + 1);
}
int main()
{
vector<int> ivec{49, 38, 65, 97, 76, 13, 27, 49};
insertSort(ivec);
print(ivec);
return 0;
}
输出结果
49 0 0 0 0 0 0 38
49 65 0 0 0 0 0 38
49 65 97 0 0 0 0 38
49 65 76 97 0 0 0 38
49 65 76 97 0 0 13 38
49 65 76 97 0 13 27 38
49 49 65 76 97 13 27 38
13 27 38 49 49 65 76 97