目录
作者想说
介于网上的算法文章大多都是死板的文字,本人文字理解能力一直不强。决定花时间做图解,把困难的问题变简单,把抽象的思维变具体。给想学习程序的小伙伴更好理解的文章资源。
文学家的浪漫是把一切用文字来书写,程序员的浪漫是把我们心中所想用代码书写
这里我将用图解来书写,程序在我脑子里的样子,我叫@张三xy,致力于写出优质作品的编程爱好者
1.希尔排序的算法简介
1.1什么是希尔排序
希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序,同时该算法是冲破O(n2)的第一批算法之一。
1.2.希尔排序的算法性能
1.2.1.时间复杂度
希尔排序时间复杂度是 O(n^(1.3-2)),空间复杂度为常数阶 O(1)。希尔排序没有时间复杂度为 O(n(logn)) 的快速排序算法快 ,因此对中等大小规模表现良好,但对规模非常大的数据排序不是最优选择,总之比一般 O(n^2 ) 复杂度的算法快得多。
1.2.2.算法稳定性
稳定排序的定义
在排序过程中,如果两个键的值相同,那么他们的相对位置不发生变化。不符合该规则的排序算法不是稳定排序算法
为什么希尔排序不稳定
因为希尔排序中有多次插入排序,单次插入排序是稳定的,不会改变相同元素的位置,但在多次的插入排序过后,相同的元素可能在各自的插入排序中移动
,最后其稳定性就会被打乱,所以shell排序是不稳定的
2.希尔排序算法的图解
2.1.第一轮排序
第一轮排序我们不断的进行排序,比较我们每一对的值,然后进行调整相对顺序,我们调整的位置我们叫做 j,我们把j 和 j - gap 的位置进行比较,然后交换
2.2.第二轮排序
第二轮排序我们缩小了增量,然后依次重复前面的操作不断比较和交换
3.希尔排序算法的代码实现
3.1.定义数组并传入到我们的希尔排序函数
int main()
{
//自定义一个数组演示
int len = 5; //数组长度
int a[] = {3,2,5,1,4};
//把数组 和 数组长度 传入到插入排序函数中
shellSort(a,len);
for (int x = 0; x < len; ++x)printf("%d ",a[x]);
return 0;
}
3.2.希尔排序函数的实现
#include <stdio.h>
/**
* 希尔排序算法
* @param a 数组
* @param len 数组长度
*/
void shellSort(int a[],int len)
{
//增量gap,逐步在缩小增量
for (int gap = len/2; gap > 0 ; gap /= 2)
{
//内部循环是一个 插入排序 用于调整位置
for(int i = gap;i < len;i++)
{
int j = i; //后置gap的位置
int val = a[j]; //当前数据项(gap后方数据项)
while(j - gap >= 0 && val < a[j - gap])
{
a[j] = a[j - gap];//前方数据项 赋值给后面
j -= gap;//找到前方数据项
}
//被插入的位置 和 i 的位置不一样,我们就进行插入操作(小优化)
if(j - gap != i)a[j] = val;
}
}
}
4.希尔排序算法的总结
由于希尔排序每轮使得整体相对有序度越来越高,所需要排序的次数越来越少,所以速度提升十分的明显,希尔排序内部是用插入排序代码实现,也可以说希尔排序是插入排序改良升级版,在大量数据下,希尔排序整体效率还是非常高