您的位置:首页 > 其它

插入排序(直接插入排序和希尔排序)

2016-05-16 20:40 477 查看
一、直接插入排序
它的思想:每次从无序表中取出第一个元素,把它插入到有序表的合适位置,使有序表仍然有序。
下面我来说一下我的思路:
1.第一趟比较前两个数,然后把第二个数按大小插入到有序表中。
2.第二趟把第三个数据与前两个数从前向后扫描,把第三个数按大小插入到有序表中。
3.依次进行下去,进行了(n-1)趟扫描以后就完成了整个排序过程。
下面我用图来帮助大家理解:


实现代码:
void InsertSort(int *arr, size_t size)
{
int end;//要排序的所有元素的最后一个元素的下标
int tmp;
for (int i = 0; i < size - 1; i++)
{
end = i;
tmp = arr[end + 1];//最后一个元素保存起来
//把所有大于最后一个元素的元素向后移动
while (arr[end]>tmp&&end >= 0)
{
arr[end + 1] = arr[end];
end--;
}
//把最后一个元素插入到不大于它的元素后面
arr[end + 1] = tmp;
}
}
二、希尔排序
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。希尔排序是非稳定排序算法。

希尔排序:将无序数组分割为若干个子序列,子序列不是逐段分割的,而是相隔特定的增量的子序列,对各个子序列进行插入排序;然后再选择一个更小的增量,再将数组分割为多个子序列进行排序......最后选择增量为1,即使用直接插入排序,使最终数组成为有序。
增量的选择:在每趟的排序过程都有一个增量,至少满足一个规则 增量关系 d[1] > d[2] > d[3] >..> d[t] = 1 (t趟排序);根据增量序列的选取其时间复杂度也会有变化,这个不少论文进行了研究,在此处就不再深究;本文采用首选增量为n/2,以此递推,每次增量为原先的1/2,直到增量为1;
下图详细讲解了一次希尔排序的过程:





代码实现:
void ShillSort(int *arr, size_t size)
{
int end;//要排序的所有元素的最后一个元素的下标
int gap = size / 2;//将数组分为size/2个子序列
int tmp;//临时值
for (gap = size / 2; gap > 0; gap /= 2)//增量递减
{
for (int i = gap; i < size ; i++)
{
if (arr[i]<arr[i - gap])
{
end = i - gap;
tmp = arr[i];
//当arr[end]>tmp时,移动
while (arr[end]>tmp&&end >= 0)
{
arr[end + gap] = arr[end];
end -= gap;
}
arr[end + gap] = tmp;
}
}
}
}
希望大家能理解,写得不够好的地方,希望大家指出来。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: