这是我参与8月更文挑战的第7天
关注我,以下内容持续更新
前面讲了直接插入排序,当较小的数在序列的偏后面的位置时,后移的次数明显增多,对效率有影响。针对这一点,希尔排序做出了优化,希尔排序通过设置一个增量gap,使得序列基本有序.提高了效率。这届主要讲希尔排序.
基本思想
将整个待排序序列分割成若干个子序列,在子序列内分别进行直接插入排序,待整个序列基本有序时,对所有元素进行直接插入排序(也就是最后一次循环gap=1的时候)。分割子序列的方法:将相隔某个增量的元素组成一个子序列,取增量的方法,令gap初始值为元素个数,每轮循环令gap除以2,算法如下:for (int gap = (int)arr.count/2; gap>0; gap/=2) {以 gap 为增量,进行组内直接插入排序};子序列内直接插入排序的思路:在插入元素 arr[i]时,自arr[i-gap]起往前跳跃式(跳跃幅度为gap)搜索待插入位置,在搜索过程中,元素后移也是跳跃 gap 个位置;在整个序列中,前 gap 个元素分别是 gap 个子序列的第一个元素,所以从 gap+1 的位置开始进行插入.
希尔排序和字节插入排序一样,有交换法和移位法,交换法效率太低,代码用移位法实现。
代码实现
-(void)shellSort:(NSMutableArray*)arr{
int gap = (int)arr.count/2;
while (gap>0) {
for (int i = gap; i<arr.count; i++) {
//暂存arr[i]的值,也就是要插入的值,使其不至于因为元素的后移而丢失元素的内容
int tmp = [arr[i] intValue];
int j = i;//j代表要插入的位置,tmp要和 j-gap 比较,如果tmp大,则插入到j-gap后面的位置,就是j
/**
while循环的条件:
j-gap>=0:如果下一个要比较的元素>=0;
tmp < arr[j-gap]:如果待插入的值小于下一个要比较的元素;往后移动
如果同时满足这两个条件,元素后移gap个位置;
退出 while 循环时,就找到正确的位置,直接插入 j 的位置
*/
while (j-gap>=0 && tmp < [arr[j-gap] intValue]) {
arr[j] = arr[j-gap];//前边的元素往后移动一位
j = j-gap;//下次比较同一子序列的前一个位置
}
arr[j] = @(tmp);//把要比较的元素插入在正确的位置
}
gap = gap/2;
}
}
//while 循环方式实现
-(void)shellSort:(NSMutableArray*)arr{
//gap从n开始,每次循环除以2
for (int gap = (int)arr.count/2; gap>0; gap/=2) {//①
for (int i = gap; i<arr.count; i++) {
//暂存arr[i]的值,也就是要插入的值,使其不至于因为元素的后移而丢失元素的内容
int tmp = [arr[i] intValue];//②
//j代表要插入的位置,tmp要和 j-gap 比较,如果tmp大,则插入到j-gap后面的位置,就是j
int j = i;
/**
while循环的条件:
j-gap>=0:如果下一个要比较的元素>=0;
tmp < arr[j-gap]:如果待插入的值小于下一个要比较的元素;往后移动
如果同时满足这两个条件,元素后移gap个位置;
退出 while 循环时,就找到正确的位置,直接插入 j 的位置
*/
while (j-gap>=0 && tmp < [arr[j-gap] intValue]) {/③
arr[j] = arr[j-gap];//前边的元素往后移动gap个位置
j = j-gap;//下次比较同一子序列的前一个位置
}
arr[j] = @(tmp);//把要比较的元素插入在正确的位置
}
}
}
代码解读
① gap从n开始,每次循环除以2,这个外层循环走了几次,就执行了几轮子序列的直接插入排序
② tmp暂存arr[i]的值,也就是要插入的值,使其不至于因为元素的后移而丢失元素的内容
③ while循环的条件:
j-gap>=0:如果下一个要比较的元素>=0;
tmp < arr[j-gap]:如果待插入的值小于下一个要比较的元素;往后移动
如果同时满足这两个条件,元素后移gap个位置;
退出 while 循环时,就找到正确的位置,直接插入 j 的位置
希尔排序与直接插入排序的对比
通过希尔排序与直接插入排序代码的比较,发现只需要把直接插入排序设置为 1 的地方,改为 gap,外层再嵌套个for循环,这个外层循环走了几次,就执行了几轮子序列的直接插入排序
其他排序算法
关注
如果觉得我写的不错 请点个赞
关注我 持续更新