希尔排序是在插入排序的基础上进行改进优化,所以学习希尔排序之前需要先了解插入排序。
插入排序
像玩扑克牌摸牌时一样,一张一张摸,每摸到一张插入到对应的位置,插入排序就是从第一个位置开始,进行插入,每次插入之插入到前面的位置,直到排序完成。平均效率为O(n方)
外层循环代表循环次数,end为准备插入牌的位置,依次向前比较,直到找到合适位置,temp为准备插入牌的值,内层循环依次对前面的值进行比较,直到找到合适位置停下。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
void InsertSort(int* a, int n)
{
for (int i = 0; i < n - 1; i++)
{
int end = i + 1;
int temp = a[end];
while (end > 0 && temp < a[end - 1])
{
a[end] = a[end - 1];
end--;
}
a[end] = temp;
}
}
int main()
{
int a[] = { 6,4,8,2,1,4,9,7,5,3,21,4,8,5 ,3,5,6,3,2,3,4,56,34,2,2,2,4,5,56,5,43 };
InsertSort(a, sizeof(a) / sizeof(int));
for (int i = 0; i < sizeof(a) / sizeof(int); i++)
{
printf("%d ", a[i]);
}
}
希尔排序
希尔排序为插入排序的优化版本,平均效率为O(nlogn),在插入排序的基础上加一个分组,定义一个gap,间隔gap的为一组,这样可以让小的数据有更快的速度到达前面,省去了插入排序的一个一个比较,每组最小的数据都在前面,然后再所以gap,再次进行分组排序,直到剩下gap为1的时候,回归到插入排序,但是这时整个数组已经基本有序,只需要少量的交换即可。
void ShellSort(int* a, int n)
{
int gap = 3;
while (gap > 1)
{
gap = gap / 3 + 1;
for (int i = 0; i < n - gap; i++)
{
int end = i + gap;
int temp = a[end];
while (end > 0 && temp < a[end - gap])
{
a[end] = a[end - gap];
end -= gap;
}
a[end] = temp;
}
}
}
int main()
{
int a[] = { 6,4,8,2,1,4,9,7,5,3,21,4,8,5 ,3,5,6,3,2,3,4,56,34,2,2,2,4,5,56,5,43 };
ShellSort(a, sizeof(a) / sizeof(int));
for (int i = 0; i < sizeof(a) / sizeof(int); i++)
{
printf("%d ", a[i]);
}
}
}
插入排序VS希尔排序 测试
- 对二者速度测试之后得出结论,在数据越多的情况下,希尔排序就越高效。
void test()
{
srand(time);
int n = 100000;
int* arr1 = (int*)malloc(sizeof(int) * n);
int* arr2 = (int*)malloc(sizeof(int) * n);
for (int i = 0; i < n; i++)
{
arr1[i] = rand();
arr2[i] = arr1[i];
}
int start1 = clock();
InsertSort(arr1, n);
int end1 = clock();
int start2 = clock();
ShellSort(arr2, n);
int end2 = clock();
printf("InsertSort: %d\n", end1 - start1);
printf("ShellSort: %d\n", end2 - start2);
}
int main()
{
test();
}
✨本文收录于数据结构理解与实现
当你喜欢一篇文章时,点赞、收藏和关注是最好的支持方式。如果你喜欢我的文章,请不要吝啬你的支持,点赞👍、收藏⭐和关注都是对我最好的鼓励。感谢你们的支持!