目录
思路:
1、将待排序序列第一个元素看作一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
2、从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。(如果待插入元素与有序序列中的某个元素相等,则将待插入元素插入到相等元素后面)
一、普通做法
void InsertSort(vector<int> &v)
{
int len = v.size();
// 从下表为1的元素选择合适位置,因为下标为0的元素只有一个,默认有序
for (int i = 1; i < len - 1; i++)
{
int temp = v[i];
// 从已经排序的序列最右边开始比较,找到比其小的数
int j = i;
while (j > 0 && temp < v[j - 1])
{
v[j] = v[j - 1];
j--;
}
// 存在比其小的数,插入
if (j != i)
v[j] = temp;
}
}
二、优化版本一
将搜索和数据后移合并为一个步骤,每次arr[i]先和前一个数据arr[i - 1]比较,如果arr[i] > arr[i - 1],则说明arr[0...i]是有序的,无需调整。否则就令j = i - 1, temp = a[i]。然后一边将数据a[j]向后移动一边向前搜索,当有数据a[j] < a[i]时停止并将temp放到a[j + 1]处。
void InsertSort(vector<int> &v)
{
int len = v.size();
int i, j, temp;
for (i = 1; i < len - 1; i++)
{
if (v[i] < v[i - 1])
{
for (j = i - 1; j >= 0 && temp < v[j]; j--)
{
v[j + 1] = v[j];
}
v[j + 1] = temp;
}
}
}
三、优化版本二
对将a[j]插入到前面a[0...j-1]的有序区间所用的方法进行改写,用数据交换代替数据后移。如果a[j]前一个数据a[j - 1] > a[j],就交换a[j]和a[j - 1],再j--直到a[j - 1] <= a[j]。这样也可以实现将一个新数据并入到有序区间。
void InsertSort(vector<int> &v)
{
int i, j;
int len = v.size();
for (i = 1; i < len - 1; i++)
{
for (j = i - 1; j >= 0 && v[j] > v[j + 1]; j--)
{
swap(v[j], v[j + 1]);
}
}
}