排序算法——希尔排序(两种实现)
之前写了快速排序和归并排序,虽然这两种排序算法问的最多,也具有一定的难度。希尔排序作为插入排序的一种,里面有着插入排序的影子。我会讲解一下希尔排序的两种实现方式。
对于希尔排序,重点在于增量。什么是增量,即希尔排序会分组进行操作,而分组的依据就是通过增量来执行的。那么增量又是什么呢?我画图来讲解一下吧~
知道了增量那么就很简单了。就是根据组内的值进行比较即可。那么希尔排序有两种方法实现:
①交换法(速度慢,不建议用)
②移位法(利用插入排序的思想进行交换法的优化,速度快,建议希尔排序用这个方法实现)
①交换法代码实现:
public static void shellSort(int arr[]){ //交换变量 int temp = 0; //第一个循环设置增量 for(int step = arr.length / 2; step > 0; step /= 2){ //第二个循环找到分组后面的数据 for(int i = step; i < arr.length; i++){ //第三个循环找到分组前面的数据 for(int j = i - step; j >= 0; j -= step){ //判断前面的值是否大于后面的值 if(arr[j] > arr[j + step]){ //交换 temp = arr[j]; arr[j] = arr[j + step]; arr[j + step] = temp; } } } } }
虽然这样的写法比较容易理解,但是效率并不高,总所周知冒泡排序是排序算法中效率很慢的,这是因为它每次都进行了数值的交换,这样会耗费大量的时间,那么这样的写法也是同样的道理。那么我们再来实现移位法。
②移位法代码实现
public static void shellSort(int arr[]){ //和交换法一样,都需要增量去分组 for(int step = arr.length / 2; step > 0; step /= 2){ //同样我们得找到分组后面的数据 for(int i = step; i < arr.length; i++){ //设置指针指向i去操作分组前的数据 int j = i; //存储当前的数据,后面数据会发生变化 temp = arr[j]; if(arr[j] < arr[j - temp]){ //要清楚j存储的是分组后面的数据 while(j - step >= 0 && temp < arr[j - step]){ //将前面的值移位到j上,此时j与j-step都为arr[j - step]的值 arr[j] = arr[j - step]; //将指针在组内往前移动,继续寻找 j -= step; } //当循环结束的时候,就是找到了位置,那么需要将temp赋值给分组前面的值 arr[j] = temp; } } } }
这样移位法就完成了,这样借助了交换法和插入排序的思想,进行代码的优化,这样的效率就会快很多了,有兴趣的可以拿这两个代码去测试一下。
下一篇:
【数据结构和算法14】归并排序