排序算法系列目录
排序算法第一讲 — 冒泡排序(Python、C++、C)
排序算法第二讲 — 选择排序(Python、C++、C)
排序算法第三讲 — 插入排序(Python、C++、C)
排序算法第四讲 — 快速排序(Python、C++、C)
排序算法第五讲 — 希尔排序(Python、C++、C)
排序算法第六讲 — 归并排序(Python、C++、C)
题目描述:
给你一个整数数组 nums,请你将该数组采用希尔排序方式进行升序排列。
希尔排序,也称递减增量排序算法,是插入排序的一种更高效的改进版本。但希尔排序是非稳定排序算法。先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序.
解题思路:
让我们先来回顾一下插入排序:
插入排序顾名思义,就是在排序的过程中,把数组的每一个元素按照大小关系,插入到前面有序区的对应位置。

怎样可以对插入排序算法做出优化呢?从以下两个方面入手:
- 在大多数元素已经有序的情况下,插入排序的工作量较小
- 在元素数量较少的情况下,插入排序的工作量较小
对原始数组进行预处理,使得大部分元素变得有序。
所谓分组,就是让元素两两一组,同组两个元素之间的跨度,都是数组总长度的一半,也就是跨度为4。
接下来,我们让每组元素进行独立排序,排序方式用直接插入排序即可。由于每一组的元素数量很少,只有两个,所以插入排序的工作量很少。每组排序完成后的数组如下:
这样一来,仅仅经过几次简单的交换,数组整体的有序程度得到了显著提高,使得后续再进行直接插入排序的工作量大大减少。
代码:
Python写法:
class Solution(object):
def solution(self, nums):
size = len(nums)
jump = size // 2 # jump 代表每次的间隔
while jump > 0:
for i in range(jump, size):
temp = nums[i]
j = i - jump # j定位比较的元素
while nums[j] > temp and j >= 0:
nums[j + jump] = nums[j]
nums[j] = temp
j = j - jump
jump = jump // 2
return nums
s = Solution()
nums = [5, 4, 38, 1]
s.solution(nums)
print(s.solution(nums))
C++写法:
#include<iostream>
using namespace std;
int main() {
int nums[100],size,i,j,jump,temp;
cin >> size;
jump = size / 2;
for(i = 0; i < size; i++){
cin >> nums[i];
}
while (jump > 0){
for(i = jump; i < size; i++){
temp = nums[i];
j = i - jump ;
while (nums[j] > temp && j >= 0){
nums[j + jump] = nums[j];
nums[j] = temp;
j = j - jump;
}
}
jump = jump / 2;
}
for(i = 0; i < size; i++) //输出排序后的结果
cout << nums[i] <<" ";
cout << "\n";
return 0;
}
C语言:
#include <stdio.h>
int main() {
int nums[100],size,i,j,jump,temp;
scanf("%d\n", &size);
jump = size / 2;
for(i = 0; i < size; i++){
scanf("%d", &nums[i]);
}
while (jump > 0){
for(i = jump; i < size; i++){
temp = nums[i];
j = i - jump ;
while (nums[j] > temp && j >= 0){
nums[j + jump] = nums[j];
nums[j] = temp;
j = j - jump;
}
}
jump = jump / 2;
}
for (i = 0; i < size; i++){
printf("%d ", nums[i]);
}
printf("\n");
return 0;
}
题目来源:
本篇博客所用图片来源于:漫画:什么是希尔排序?
题目来源: