这里我们就实现这俩个,我觉的有点太多了的话,我们也看不进去,我把剩下的,《选择排序》《交换排序》《归并排序》《非比较排序》在另外写几篇博客,我会把下面的链接到时候发在下面,这样就比较好看;
《插入排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89345756
《选择排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89363420
《交换排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89394853
《归并排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89449893
《非比较排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89449893
排序:所谓的排序,大概的意思就是让无序的数列,变成有序。
一,插入排序
首先,我们要先了解一下,插入排序的思想:就是把待排序按其关键码值插入到有序的排列中,直到所有的排序都排完,完成一个新的序列。
(1)直接插入排序
直接插入的思想就是:《这里主要是我都思想》将进行插入一个值的时候, 就把前面插入进去,并且已近排序好了的顺序,在于之前的遍历一遍,找到合适的位置,然后在插入到此排序链中,形成行的排序,重复此过程就完成排序了。
下面我们看一下实现的代码;
#include<stdlib.h>
#include<stdio.h>
#include<time.h>
#include<malloc.h>
void Print(int* a, int n) //实现函数的调用
{
int i = 0;
for (i = 0; i <= n - 1; i++)
{
printf("%d ", a[i]);
}
printf("\n");
}
void InsertSort(int* a, int n) //插入排序——直接插入
{
int i = 0;
for (i = 0; i < n - 1; i++)
{
int end = i;
int tmp = a[end + 1];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + 1] = a[end];
--end;
}
else
{
break;
}
}
a[end + 1] = tmp;
}
}
int main()
{
int a[] = { 1, 2, 5, 6, 9, 8, 7, 4, 3 };
InsertSort(a, sizeof(a) / sizeof(int));
Print(a, sizeof(a) / sizeof(int));
return 0;
}
这里就是我们实现的在插入排序中的直接插入排序,很简单,也很好理解,好好看一下代码,不理解的话,可以在下面的评论区群论,哈哈
(2)希尔排序
希尔排序的思想:(这里主要是我的理解)主要就是,我们先选择一个整数,按照一定的间距,然后排序,比如,间隔为2.就是 1,3,5,7,9等等排过去,把第一遍遍历过后,然后在下面的时候第二次便利的时候,我们把组织然后再变一下,比如第二次变成1,2,3,4,5,6这样遍历,我们把选定的值成为 gap,然后让gap变就可以了,重复上面的循环,这样就是实现希尔排序;
下面,我们先看一下,我画的图片,比较容易理解;
下面我们就是实现希尔排序,看一下实现代码:
void ShellSort(int* a, int n)
{
int i = 0;
int gap = n;
int end = 0;
int tmp = 0;
while (gap > 1)
{
gap = gap / 3 + 1; //这里为什么是这个,在下面的时候,我会解释;
for (i = 0; i <= n - gap - 1; i++)
{
end = i;
tmp = a[end + gap];
while (end >= 0)
{
if (a[end] > tmp)
{
a[end + gap] = a[end];
end -= gap; //间距是gap,每次比较的也是gap
}
else
{
break;
}
a[end + gap] = tmp;
}
}
}
}
我相信,大家在疑惑为什么是:gap = gap / 3 + 1;,那是因为,比如我们是7个数,我们除3,取中间的值那应该是3,但是我们算下来是2,所以要加你,且这次gap的间隔是3,下次我们还要减小,但剩下2,或者3个数的时候,我们除,就是0,或者1,不对,我们要的是 1 或者是 2 ,所以我们要在这里加1;
下面我们再看一下,这两种排序的实现快慢,且在常用的时候使用哪一种方法比较好?
我们看一下下面的一段代码,我们来跑一下:
void TestSortOP()
{
const int n = 100000;
int* a1 = (int*)malloc(sizeof(int)*n);
int* a2 = (int*)malloc(sizeof(int)*n);
srand(time(0));
for (int i = 0; i < n; ++i)
{
a1[i] = rand();
a2[i] = a1[1];
}
size_t begin1 = clock();
InsertSort(a1, n);
size_t end1 = clock();
size_t begin2 = clock();
ShellSort(a2, n);
size_t end2 = clock();
printf("%u\n", end1 - begin1);
printf("%u\n", end2 - begin2);
}
我们看一下执行的程序;
当我们随机给出100000个数据的时候,插入排序用了10s多,儿希尔排序用了不到一秒,相当于0秒一样,通过测试,我们就可以看出,希尔排序的速度是非常块,建议的话,我们如果要使用插入排序的话,那么就是用希尔排序;
下面我们来总结一下直接插入排序和希尔排序;
我们先看一下直接插入排序;
我们通过上面的复习,我们知道:
1. 元素集合越接近有序,直接插入排序算法的时间效率越高
2. 时间复杂度:O(N^2)
3. 空间复杂度:O(1),它是一种稳定的排序算法
4. 稳定性:稳定
下面我们再看一下希尔排序:
通过我们上面的学习;
1.希尔排序是对直接排序的优化
2. 时间复杂度:O(N^1.3 ~ N ^2)
3.稳定性:稳定
4. 当gap>1的时候。都是预排序,只有当gap==1的时候,数组就已经接近有序了,这时候就算是完成排序了;
这里我们就实现这俩个,我觉的有点太多了的话,我们也看不进去,我把剩下的,《选择排序》《交换排序》《归并排序》《非比较排序》在另外写几篇博客,我把下面的链接发在下面;
《插入排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89345756
《选择排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89363420
《交换排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89394853
《归并排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89449893
《非比较排序》链接:https://blog.csdn.net/dpfxaca6/article/details/89449893