Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Shell Sort Sorting Algorithm #364

Merged
merged 4 commits into from
Apr 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Complete solutions to [LeetCode](https://leetcode-cn.com/problemset/all/), [LCOF
- [Selection Sort](/basic/sorting/SelectionSort/README.md)
- [Merge Sort](/basic/sorting/MergeSort/README.md)
- [Quick Sort](/basic/sorting/QuickSort/README.md)
- [Shell Sort](/basic/sorting/ShellSort/README.md)

### Searching

Expand Down
1 change: 1 addition & 0 deletions basic/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
- [Selection Sort](./sorting/SelectionSort/README.md)
- [Merge Sort](./sorting/MergeSort/README.md)
- [Quick Sort](./sorting/QuickSort/README.md)
- [Shell Sort](./sorting/ShellSort/README.md)

## Searching

Expand Down
2 changes: 1 addition & 1 deletion basic/sorting/MergeSort/MergeSort.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ private static void merge(int[] nums, int low, int mid, int high, int[] temp) {
}
}

System.arraycopy(tmp, low, nums, low, high - low + 1);
System.arraycopy(temp, low, nums, low, high - low + 1);
}

private static void mergeSort(int[] nums, int low, int high, int[] temp) {
Expand Down
81 changes: 81 additions & 0 deletions basic/sorting/ShellSort/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# 希尔排序

希尔排序,也被称为递减增量排序,是简单插入排序的一种改进版本。

- 在插入排序中,如果待排序列中的某个元素,距离有序数列中待插入位置非常远,就需要比较很多次才可以到达插入位置,这是因为待插入元素局部非常无序,比如说`[2, 3, 4, 5, 6, 7, 8, 1, ...]`,我们要插入 1,就必须将 1 和前面的 2-8 每个值都比较一下,就是因为 1 附近非常无序,想象一下,如果待插入元素附近比较有序,那么在进行插入排序的时候就只需要比较非常少的几次就可以插入到正确位置。
- 希尔排序就是先把整个序列排得相对比较有序,再进行插入排序的时候,需要比较的次数就会变得很少。
- 插入排序的增量(间隔)为 1,希尔排序相当于将这个间隔从最大为数组长度的一半一直降到 1,这一点在程序中体现的很清楚。当间隔很大时,比较的次数也会很少,在进行了几次大间隔的插入排序后,序列已经部分有序,这样再进行小间隔的插入排序也自然会比较很少的次数。
- 希尔排序就是将处在相同间隔的元素提取出来单独进行插入排序,然后逐步将间隔减小到 1 的过程。

## 代码示例

<!-- tabs:start -->

### **Java**

```java
import java.util.Arrays;

public class ShellSort {

private static int[] shellSort(int[] arr) {
int n = arr.length;

for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int key = arr[i];
int j = i;
while (j >= gap && arr[j - gap] > key) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = key;
}
}
return arr;
}

public static void main(String[] args) {
System.out.println(Arrays.toString(shellSort(new int[]{1, 2, 7, 9, 5, 8})));
}
}
```

### **JavaScript**

```javascript
function shellSort(arr) {
var len = arr.length;
var gapSize = Math.floor(len / 2);
while (gapSize > 0) {
for (var i = gapSize; i < len; i++) {
var temp = arr[i];
var j = i;

while (j >= gapSize && arr[j - gapSize] > temp) {
arr[j] = arr[j - gapSize];
j -= gapSize;
}
arr[j] = temp;
}
gapSize = Math.floor(gapSize / 2);
}
return arr;
}

let arr = [6, 3, 2, 1, 5];
console.log(shellSort(arr));
```

<!-- tabs:end -->

## 算法分析

时间复杂度:

希尔排序的时间性能取决于所取“增量”序列的函数,这涉及到一些数学上尚未解决的难题。但是有人通过大量的实验,给出了较好的结果:当 n 较大时,比较和移动的次数约在 `n^1.25` 到 `(1.6n)^1.25` 之间。所以可以这样简单记忆:

- 当 n 较小时,希尔排序和插入排序相差不大,都为 n² 左右。
- 当 n 很大时,时间增长幅度逐渐放缓,平均复杂度是 nlogn。

空间复杂度:O(1)。
25 changes: 25 additions & 0 deletions basic/sorting/ShellSort/ShellSort.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import java.util.Arrays;

public class ShellSort {

private static int[] shellSort(int[] arr) {
int n = arr.length;

for (int gap = n / 2; gap > 0; gap /= 2) {
for (int i = gap; i < n; i++) {
int key = arr[i];
int j = i;
while (j >= gap && arr[j - gap] > key) {
arr[j] = arr[j - gap];
j -= gap;
}
arr[j] = key;
}
}
return arr;
}

public static void main(String[] args) {
System.out.println(Arrays.toString(shellSort(new int[]{1, 2, 7, 9, 5, 8})));
}
}
21 changes: 21 additions & 0 deletions basic/sorting/ShellSort/ShellSort.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
function shellSort(arr) {
var len = arr.length;
var gapSize = Math.floor(len / 2);
while (gapSize > 0) {
for (var i = gapSize; i < len; i++) {
var temp = arr[i];
var j = i;

while (j >= gapSize && arr[j - gapSize] > temp) {
arr[j] = arr[j - gapSize];
j -= gapSize;
}
arr[j] = temp;
}
gapSize = Math.floor(gapSize / 2);
}
return arr;
}

let arr = [6, 3, 2, 1, 5];
console.log(shellSort(arr))