# andyRon/swift-algorithm-club-cn

Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.

# 希尔排序(Shell Sort)

Sapientia大学创建了一个很好的视频，显示了匈牙利民间舞蹈的过程。（译注：类似希尔排序的过程，油管视频需要翻墙）

## 例子

``````n = floor(9/2) = 4
``````

``````sublist 0:  [ 64, xx, xx, xx, 72, xx, xx, xx, 4  ]
sublist 1:  [ xx, 20, xx, xx, xx, 10, xx, xx, xx ]
sublist 2:  [ xx, xx, 50, xx, xx, xx, 23, xx, xx ]
sublist 3:  [ xx, xx, xx, 33, xx, xx, xx, -1, xx ]
``````

``````sublist 0:  [ 4, xx, xx, xx, 64, xx, xx, xx, 72 ]
``````

``````sublist 1:  [ xx, 10, xx, xx, xx, 20, xx, xx, xx ]
sublist 2:  [ xx, xx, 23, xx, xx, xx, 50, xx, xx ]
sublist 3:  [ xx, xx, xx, -1, xx, xx, xx, 33, xx ]
``````

``````[ 4, 10, 23, -1, 64, 20, 50, 33, 72 ]
``````

``````n = floor(4/2) = 2
``````

``````sublist 0:  [  4, xx, 23, xx, 64, xx, 50, xx, 72 ]
sublist 1:  [ xx, 10, xx, -1, xx, 20, xx, 33, xx ]
``````

``````sublist 0:  [  4, xx, 23, xx, 50, xx, 64, xx, 72 ]
sublist 1:  [ xx, -1, xx, 10, xx, 20, xx, 33, xx ]
``````

``````[ 4, -1, 23, 10, 50, 20, 64, 33, 72 ]
``````

``````n = floor(2/2) = 1
``````

gap 大小为1表示我们只有一个子列表，即数组本身，我们再次调用`insertionSort()`对其进行排序。 最终排序的数组是：

``````[ -1, 4, 10, 20, 23, 33, 50, 64, 72 ]
``````

## gap 序列

gap 序列”确定 gap 的初始大小以及每次迭代如何使 gap 变小。 良好的 gap 序列对于希尔排序表现良好非常重要。

## 只是为了好玩...

``````61200 REM S is the array to be sorted
61205 REM AS is the number of elements in S
61210 W1=AS
61220 IF W1<=0 THEN 61310
61230 W1=INT(W1/2): W2=AS-W1
61240 V=0
61250 FOR N1=0 TO W2-1
61260 W3=N1+W1
61270 IF S(N1)>S(W3) THEN SH=S(N1): S(N1)=S(W3): S(W3)=SH: V=1
61280 NEXT N1
61290 IF V>0 THEN 61240
61300 GOTO 61220
61310 RETURN
``````

## 代码

``````public func insertSort(_ list: inout[Int], start: Int, gap: Int) {
for i in stride(from: (start + gap), to: list.count, by: gap) {
let currentValue = list[i]
var pos = i
while pos >= gap && list[pos - gap] > currentValue {
list[pos] = list[pos - gap]
pos -= gap
}
list[pos] = currentValue
}
}

public func shellSort(_ list: inout [Int]) {
var sublistCount = list.count / 2
while sublistCount > 0 {
for pos in 0..<sublistCount {
insertionSort(&list, start: pos, gap: sublistCount)
}
sublistCount = sublistCount / 2
}
}

var arr = [64, 20, 50, 33, 72, 10, 23, -1, 4, 5]

shellSort(&arr)
``````

## 扩展阅读

Rosetta code的希尔排序（译注：大概70种不同语言实现希尔排序😅😓