插入排序
插入排序,一般也被称为直接插入排序。对于少量元素的排序,它是一个有效的算法。插入排序是一种最简单的排序方法,它的基本思想是将一个记录插入到已经排好序的有序表中,从而一个新的、记录数增1的有序表。在其实现过程使用双层循环,外层循环对除了第一个元素之外的所有元素,内层循环对当前元素前面有序表进行待插入位置查找,并进行移动 。
排序算法的稳定性
假定在待排序的记录序列中,存在多个具有相同的关键字的记录,若经过排序,这些记录的相对次序保持不变,即在原序列中,r[i]=r[j],且r[i]在r[j]之前,而在排序后的序列中,r[i]仍在r[j]之前,则称这种排序算法是稳定的;否则称为不稳定的。
直接插入排序,稳定
void StraightInsertionSort(int R[], int n)
{
int i, j;
int temp;
for (i = 1; i < n; ++i)
{
temp = R[i]; //将待插入关键字暂存于temp中
j = i - 1;
/*下面这个循环完成了从待排关键字之前的关键字开始扫描,
如果大于待排关键字,则后移一位*/
while (j >= 0 && temp < R[j])
{
R[j + 1] = R[j];
--j;
}
R[j + 1] = temp; //找到插入位置,将temp中暂存的待排关键字插入
}
}
折半插入排序,稳定
void HalfInsertionSort(int R[], int n)
{
int i, j;
int temp,low,high,mid;
for (i = 1; i < n; ++i) //一共进行n-1次插入
{
temp = R[i]; //将待插入关键字暂存于temp中
//进行折半查找
low = 0;
high = i - 1;
while (low <= high)
{
mid = (low + high) / 2;
if (temp < R[mid])
{
high = mid - 1;
}
else
{
low = mid + 1;
}
}
cout << "low=" << low << ",high=" << high << endl;
/*折半查找结束后,low和high的关系为:low = high+1
插入位置在 high+1 处*/
//找到位置后,进行移动
for (j = i - 1; j >= high + 1; --j)
{
R[j + 1] = R[j];
}
R[high + 1] = temp;//也可写成:R[low] = temp;
}
}
希尔排序,不稳定
void ShellSort(int R[], int n)
{
int i, j;
int temp;
//增量选取采用:Shell idea
for (int dk = n / 2; dk >= 1; dk = dk / 2) {
//走一步,下面代码为所有的组同时进行排序
for (i = dk; i < n; ++i)
if (R[i] < R[i - dk])
{
temp = R[i]; //将待插入关键字暂存于temp中
//比较的同时,进行移动
for (j = i - dk; j >= 0 && temp < R[j]; j -= dk)
{
R[j + dk] = R[j];
}
R[j + dk] = temp;
}
}
}