007 数据结构 _ 插入排序与希尔排序——“C”
前言
本文将会向您介绍插入排序与希尔排序的实现,文中附有详细的图文分解哦!!!
一、插入排序是什么
插入排序:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序的有序序列中,直到所有的记录插入完为止,得到一个新的有序序列(实际上我们玩扑克牌的时候就利用了插入排序的思想)
以下是直接插入排序的动图展示
当插入第i(i>=1)个元素时,前面的array[0],array[1],…,array[i-1]已经排好序,此时用array[i]的排序码与array[i-1],array[i-2],…的排序码顺序进行比较,找到插入位置即将array[i]插入,原来位置上的元素顺序后移
已经过测试,请放心学习
Insert代码实现
void InsertSort(int* a, int n)
{
for (int i = 0; i < n-1; i++)
{
int end = i;
int tmp = a[end + 1]; //保存a[end+1]
while (end >= 0)
{
if (tmp < a[end]) //如果后一个即将要插入的数比前一个小
{
a[end + 1] = a[end]; //将前一个数向后移动一位
end--;
}
else
{
break;
}
}
a[end + 1] = tmp; //将tmp插入
}
}
void print(int* a,int n)
{
for (int i = 0; i < n; i++)
{
printf("%d ", a[i]);
}
}
int main()
{
int a[] = { 4,7,1,9,3,6,5,8,3,2,0 };
int n = sizeof(a) / sizeof(a[0]);
InsertSort(a, n);
print(a, n);
return 0;
}
这里仅是对前两个数的插入进行了分解,后续的插入无非也是后一个数比前一个数小或者大
各位可以画图走读代码。
二、希尔排序是什么
希尔排序法的基本思想是:先选定一个整数gap(间隔),把待排序文件中所有记录分成gap组,所有距离为的记录分在同一组内,并对每一组内进行类似直接插入排序的过程。当到达gap = 1时,所有记录在统一组内排好序。
当gap = 1时,且这组数(9,8,7,6,5,4,3,2,1为倒序的时候),(我们的需求是升序)即array [end+1] < array [end] 时,需要将array [end]向后挪动,将array [end + 1]向前插入,这时的效率就会非常低下。
因此我们引入了希尔排序,当gap > 1时进行预排序。当gap = 1时进行直接插入排序(此时的一组数接近有序,再进行gap = 1的直接插入排序,将会提高效率)
以下是当gap = 5,gap = 2,gap = 1时的三趟排序,当gap > 1时仅是预排序,让这一组数接近有序
Shell代码实现
void ShellSort(int* a, int n)
{
int gap = n;
while (gap > 1)
{
gap = gap / 3 + 1; //保证最后一次gap为1
for (int i = 0; i < n - gap; i++)
{
int end = i;
int tmp = a[end + gap];
while (end >= 0)
{
if (tmp < a[end])
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break; //当tmp > a[end]时跳出循环
}
}
a[end + gap] = tmp;
}
}
}
以上代码与直接插入排序的代码有异曲同工之处,当gap=1时就是插入排序
对一组{4, 7, 1, 3, 6, 5, 8, 3, 2}数据进行排序
预排序:gap = 4
ps:当end = i = 4时,注意这段代码( tmp = a[8] )
当a[4]与a[8]比较后,并把a[4]移动到a[8]后,end -= gap,此时end = 0
那也就意味着tmp会与a[0]进行比较调整,如上图
while (end >= 0)
{
if (tmp < a[end])
{
a[end + gap] = a[end];
end -= gap;
}
else
{
break; //当tmp > a[end]时跳出循环
}
}
预排序:gap = 2
在此之前的预排序将会大大提高后续排序的效率
gap = 1
ps: 与插入排序的实现一模一样
小结
本文介绍了插入排序与希尔排序,并对步骤进行分解,希望能给你带来些收获,若本文存在疏漏或错误的地方,还请您能够指出,祝您天天开心啦!