希尔排序法介绍
希尔排序是希尔(Donald Shell)于1959年提出的一种排序算法。希尔排序也是一种插入排序,它是简单插入排序经过改进之后的一个更高效的版本,也称为缩小增量排序。
希尔排序法基本思想
希尔排序是把记录按下标的一定增量分组,对每组使用直接插入排序算法排序;随着增量逐渐减少,每组包含的关键词越来越多,当增量减至1时,整个文件恰被分成一组,算法便终止
希尔排序算法应用实例
希尔排序原发示意图
交换法希尔排序==》效率太慢==比插入排序慢太多
// 完整的交换法希尔排序
public static void shell(int[] arr){
int temp=0;//定义临时变量
// 最外层循环控制分的组数和步长==》【步长=组数】==》这两个是对应关系
for (int gap = arr.length/2; gap > 0; gap/=2) {
// 先以第一趟进行举例分析
// 首先先根据数组的大小将数据分组==》组数=数组数据个数/2
for (int i = gap; i <arr.length ; i++) {//控制内循环将元素从0索引开始,根据正确的步长,进行正确的两个数的比较
for (int j = i-gap; j >= 0 ; j-=gap) {//控制每一组的一个元素,根据步长(步长=分的组数)找出对应的元素进行比较,大的往后移动(类似冒泡)
if (arr[j]>arr[j+gap])
{
temp=arr[j];
arr[j]=arr[j+gap];
arr[j+gap]=temp;
}
}
}
}
}
// 第一次分组的分析
public static void shellAnalyze(int[] arr)
{
int temp=0;//定义临时变量
// 先以第一趟进行举例分析
// 首先先根据数组的大小将数据分组==》组数=数组数据个数/2
for (int i = 5; i <arr.length ; i++) {//控制内循环将元素从0索引开始,根据正确的步长,进行正确的两个数的比较
for (int j = i-5; j >= 0 ; j-=5) {//控制每一组的一个元素,根据步长(步长=分的组数)找出对应的元素进行比较,大的往后移动(类似冒泡)
if (arr[j]>arr[j+5])
{
temp=arr[j];
arr[j]=arr[j+5];
arr[j+5]=temp;
}
}
}
}
移动法(移位法)希尔排序==>效率较高
帮助理解的图示
// 效率最快的希尔排序
public static void shellInsert(int[] arr)
{
for (int gap = arr.length/2; gap > 0; gap/=2) {//太牛逼了!!!!!
for (int i = gap; i <arr.length ; i++) {//将i的初始值设为步长的值,目的就是比较同组中前两个元素,随着i的每一次加1,实现比较同组中所有的元素
int j=i;//保存待插入的索引
int temp=arr[j];//用临时变量存储待拆入的数==》临时存储变量的用于,如果遇到小的元素需要向前移动数据,
if (arr[j]<arr[j-gap])//如果小于说明同一组中后面的元素小于前面的元素,需要进行插入排序
{
/*
* j-gap>=0:条件成立说明同一组中,前面还有元素可以比较
* temp<arr[j-gap]:说明当前元素,同一组中的前面的元素小,需要进行交换
* */
while (j-gap>=0 && temp<arr[j-gap])
{
arr[j]=arr[j-gap];//将数值大的元素存储在数据小的位置==》意图就是交换位置,将大元素向后移动
// j=j-gap;//根据固定的步长正确的将索引移动到当前元素的前面一个位置
j-=gap;
}
arr[j]=temp;//将元素小的值移动到前面
}
}
}
}