目录
一、排序思想
1、直接插入排序
2、希尔排序
二、代码实现
三、性能比较
四、排序总结
1、直接插入排序
2、希尔排序
一、排序思想
1、直接插入排序
基本思想:把待排序的序列选取一个整数逐个插入到已经排好的有序序列中,直到所有整数都插入到这个有序序列中,得到一个新的有序序列。
2、希尔排序
基本思想:在直接插入排序的基础上进行了优化,选取一个整数gap,把每个距离为gap的数分为一组,并对每一组内的数进行预排序,得到接近有序的序列。更改gap,直到gap==1时,得到一个新的有序序列。
二、代码实现
//直接插入排序
void InsertSort(int* a, int n)
{
//先走单趟 再走整体
//[0,end]有序,把end+1位置的值插入 保持有序
for (int i = 0; i < n - 1; i++)
{
int end=i;
int tmp = a[end + 1];
while (end >= 0)
{
//排升序
if (tmp < a[end])
{
a[end + 1] = a[end];
end--;
}
else
{
//只要tmp>=a[end]就跳出循环
break;
}
}
a[end + 1] = tmp;
}
}
//希尔排序
void ShellSort(int* a, int n)
{
int gap = n;
while (gap > 1)
{
gap = gap / 3+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
//只要tmp>=a[end]就跳出循环
break;
}
a[end + gap] = tmp;
}
}
}
三、性能比较
//随机生成100000个数,插入到在堆上开辟的数组中,并对该数组进行排序
//测试两个排序所用时间
void TestOP()
{
srand(time(0));
const int N = 100000;
int* a1 = (int*)malloc(sizeof(int) * N);
int* a2 = (int*)malloc(sizeof(int) * N);
//memset(a1, 0, sizeof(int) * N);
for (int i = 0; i < N; i++)
{
a1[i] = rand();
a2[i] = a1[i];
}
int begin1 = clock();
InsertSort(a1, N);
int end1 = clock();
int begin2 = clock();
ShellSort(a2, N);
int end2 = clock();
printf("InsertSort:%d\n", end1 - begin1);
printf("ShellSort:%d\n", end2 - begin2);
free(a1);
free(a2);
}
int main()
{
TestOP();
return 0;
}
//运行结果
InsertSort:3700
ShellSort:16
四、排序总结
1、直接插入排序
<1>、元素集合越接近有序,直接插入排序的时间效率就越高,最坏情况是逆序
<2>、时间复杂度:O(n^2)
<3>、空间复杂度:O(1)
<4>、稳定性:它是一种稳定的排序算法
2、希尔排序
<1>、希尔排序是对直接插入排序的进一步优化,当gap>1时都是进行预排序,目的是让数组更有序,当gap==1时,数组已经接近有序,整体达到对直接插入排序的优化。
<2>、时间复杂度:O(n^1.3)
<3>、空间复杂度:O(1)
<4>、稳定性:它是一种不稳定的排序算法