十大经典排序算法

算法说明

十大排序算法分别是:

冒泡排序、选择排序、插入排序、希尔排序、归并排序、快速排序、堆排序、计数排序、桶排序、基数排序

Python版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
#!/usr/bin/python
# coding=utf-8


import sys
import os
import math

def bubbleSort(arr):
'''
冒泡排序
'''
length = len(arr)
if length < 2:
return arr

for i in range(1, length, 1):
for j in range(0, length-i, 1):
if arr[j] > arr[j+1]:
# arr[j],arr[j+1] = arr[j+1],arr[j]
arr[j] = arr[j] + arr[j+1]
arr[j+1] = arr[j] - arr[j+1]
arr[j] = arr[j] - arr[j+1]
# print("冒泡排序:" + str(arr))
print("bubbleSort:" + str(arr))
return arr

def selectSort(arr):
'''
选择排序
'''
length = len(arr)
if length < 2:
return arr

for i in range(0, length):
index = i
for j in range(i+1, length):
if arr[j] < arr[index]:
index = j
if index != i:
arr[i],arr[index] = arr[index],arr[i]
# print("选择排序:" + str(arr))
print("selectSort:" + str(arr))
return arr

def insertSort(arr):
'''
插入排序
'''
length = len(arr)
if length < 2:
return arr

gap = 1
for i in range(0, length):
index = i-gap
value = arr[i]
while index >= 0:
if arr[index] > value:
arr[index+1] = arr[index]
index -= 1
else:
break
# while index >= 0 and arr[index] > value:
# arr[index+1] = arr[index]
# index -= 1
arr[index+1] = value
# print("插入排序:" + str(arr))
print("insertSort:" + str(arr))
return arr

def shellSort(arr):
'''
希尔排序
'''
lenght = len(arr)
if lenght < 2:
return arr

gap = lenght//2
while gap > 0:
for i in range(0,lenght):
index = i - gap
value = arr[i]
while index >= 0 and arr[index]>value:
arr[index+gap] = arr[index]
index -= gap
arr[index+gap] = value
gap = gap//2
# print("希尔排序:" + str(arr))
print(" shellSort:" + str(arr))
return arr

def mergeSort(arr):
'''
归并排序
'''
def mergeData(left,right):
result = []
while len(left)>0 and len(right):
if left[0] > right[0]:
result.append(right.pop(0))
else:
result.append(left.pop(0))
while len(left)>0:
result.append(left.pop(0))
while len(right)>0:
result.append(right.pop(0))
return result

def devide(arr):
length = len(arr)
if length < 2:
return arr
middle = length//2
left = arr[0:middle]
right = arr[middle:length]
return mergeData(devide(left),devide(right))

length = len(arr)
if length < 2:
return arr
result = devide(arr)
# print("归并排序:" + str(result))
print(" mergeSort:" + str(result))
return result

def quickSort(arr):
'''
快速排序
'''
def pivotSort(arr,start,end):
pivotValue = arr[end]
index = start
j = start
while j < end:
if arr[j] < pivotValue:
arr[index],arr[j] = arr[j],arr[index]
index += 1
j += 1
arr[index],arr[end] = arr[end],arr[index]
return index

def pivotSort2(arr,start,end):
pivot = arr[start]
while start < end:
while start < end and arr[end] > pivot:
end -= 1
arr[start] = arr[end]
while start < end and arr[start] <= pivot:
start += 1
arr[end] = arr[start]
arr[start] = pivot
return start

def quickSortStart(arr,start,end):
if start < end:
# pivotIndex = pivotSort(arr,start,end)
pivotIndex = pivotSort2(arr,start,end)
quickSortStart(arr,start,pivotIndex-1)
quickSortStart(arr,pivotIndex+1,end)
return arr

length = len(arr)
if length < 2:
return arr
result = quickSortStart(arr,0,len(arr)-1)
# print("快速排序:" + str(result))
print(" quickSort:" + str(result))
return result

def heapSort(arr):
'''
堆排序
'''
arrLength = len(arr)
if arrLength < 2:
return arr

def swap(arr,i,j):
arr[i],arr[j] = arr[j],arr[i]

def heapify(arr,i):
left = 2*i + 1
right = 2*i + 2
largest = i
if left < arrLength and arr[left] > arr[largest]:
largest = left
if right < arrLength and arr[right] > arr[largest]:
largest = right
if largest != i:
swap(arr,i,largest)
heapify(arr,largest)

def buildMaxHeap(arr):
# for i in range(math.floor(len(arr)/2),-1,-1):
for i in range(len(arr)/2,-1,-1):
heapify(arr,i)

buildMaxHeap(arr)
for i in range(len(arr)-1,0,-1):
swap(arr,0,i)
arrLength -= 1
heapify(arr,0)
# print(" 堆排序:" + str(arr))
print(" heapSort:" + str(arr))
return arr

def countSort(arr):
'''
计数排序
'''
arrLength = len(arr)
if arrLength < 2:
return arr

minValue = 0
maxValue = 0
for item in arr:
minValue = min(minValue,item)
maxValue = max(maxValue,item)
# 计算得到临时数组的长度
bucketLen = (maxValue - minValue) + 1
# 初始化临时数组
bucket = [0 for i in range(bucketLen)]
# 源数组的值为key,出现次数为value存储到临时数组
for item in arr:
bucket[item-minValue] += 1
# 新建结果数组
result = [0 for i in range(arrLength)]
index = 0
for i in range(0,bucketLen):
while bucket[i] > 0:
result[index] = i+minValue
index += 1
bucket[i] -= 1
# print(" 计数排序:" + str(result))
print(" countSort:" + str(result))
return result

def bucketSort(arr):
'''
桶排序
'''
arrLength = len(arr)
if arrLength < 2:
return arr
minValue = 0
maxValue = 0
for item in arr:
minValue = min(minValue,item)
maxValue = max(maxValue,item)
# 计算得到桶数量
bucketNum = (maxValue - minValue)/arrLength + 1
# 初始化桶
# bucket = [[]]*n操作中,只是创建n个指向list的引用,一旦list改变,bucket中n个list也会随之改变。
# 需要使用间接定义的方式创建二维数组
bucket = [[] for i in range(bucketNum)]
# 将源数组的元素放入各个桶中
for item in arr:
num = (item - minValue)/arrLength
currentBucket = bucket[num]
currentBucket.append(item)
# 各个桶中元素排序
for item in bucket:
quickSort(item)
# 获取所有桶排序后的数据
index = 0
for item in bucket:
for value in item:
arr[index] = value
index += 1
print("bucketSort:" + str(arr))
return arr

def radixSort(arr):
'''
基数排序
'''
arrLength = len(arr)
if arrLength < 2:
return arr
def getMax(arr):
maxValue = arr[0]
for item in arr:
maxValue = max(item,maxValue)
return maxValue

def digitsCountSort(arr,exp):
# 存储"被排序数据"的临时数组
output = [0 for i in range(arrLength)]
# 每一位的数字只能是[0-9),所以默认新建长度为10的数组
bucket = [0 for i in range(10)]
# 源数组当前为数的值为key,出现次数为value存储到临时数组
for i in range(0,arrLength):
num = (arr[i]/exp)%10
bucket[num] += 1
# 这里修改后使得buckets[i]的值就是排序后该数据在源数组中应处的位置
for i in range(1,10):
bucket[i] += bucket[i-1]
# 将数据存储到临时数组output[]中
for i in range(arrLength-1,-1,-1):
num = (arr[i]/exp)%10
output[bucket[num]-1] = arr[i]
bucket[num] -= 1
# 将排序好的数据赋值给a[]
for i in range(0,arrLength):
arr[i] = output[i]

maxValue = getMax(arr)
# 指数。当对数组按各位进行排序时,exp=1;按十位进行排序时,exp=10;...
exp = 1
while maxValue/exp > 0:
#从个位数开始,对数组按exp位数进行桶排序
digitsCountSort(arr,exp)
exp = exp * 10
print(" radixSort:" + str(arr))
return arr

Swift版本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
class Sort: NSObject {

/// 冒泡排序
static func bubbleSort(_ data:Array<Int>)->Any{
var dataAry:Array<Int> = data
let num = dataAry.count - 1
if num < 1 {
return dataAry
}
for i in 1...num {
for j in 0...(num-i) {
if dataAry[j] > dataAry[j+1] {
let temp = dataAry[j+1]
dataAry[j+1] = dataAry[j]
dataAry[j] = temp
}
}
}
print("冒泡排序:",dataAry)
return dataAry
}

/// 选择排序
static func selectSort(_ data:Array<Int>)->Any {
var dataAry:Array<Int> = data
let num = dataAry.count - 1
if num < 1 {
return dataAry
}

for i in 0...num-1 {
var index:Int = i
for j in i+1...num {
if dataAry[j] < dataAry[index] {
index = j
}
}
if index != i {
let temp = dataAry[i]
dataAry[i] = dataAry[index]
dataAry[index] = temp
}
}
print("选择排序:",dataAry)
return dataAry
}

/// 插入排序
static func insertSort(_ data:Array<Int>) -> Any {
var dataAry:Array<Int> = data
let num = dataAry.count - 1
if num < 1 {
return dataAry
}
for i in 0...num {
let value = dataAry[i]
var index = i-1
while index >= 0 {
if dataAry[index] > value {
dataAry[index+1] = dataAry[index]
index -= 1
}else{
break
}
}
dataAry[index+1] = value
}
print("插入排序:",dataAry)
return dataAry
}

/// 希尔排序
static func shellSort(_ data:Array<Int>)->Any {
var dataAry:Array<Int> = data
let num = data.count - 1
if num < 1 {
return dataAry
}
var gap = num/2
while gap > 0 {
for i in 0...num {
let value = dataAry[i]
var index = i - gap
while index >= 0 {
if dataAry[index] > value {
dataAry[index+gap] = dataAry[index]
index -= gap
}else{
break
}
}
dataAry[index+gap] = value
}
gap = gap/2
}
print("希尔排序:",dataAry)
return dataAry
}

/// 归并排序
static func mergeSort(_ data:Array<Int>)->Any {
let dataAry:Array<Int> = data
let num = data.count - 1
if num < 1 {
return dataAry
}

func mergeData(_ left:Any, _ right:Any)->Any {
var result:Array<Int> = []
var leftData:Array<Int> = left as! Array<Int>
var rightData:Array<Int> = right as! Array<Int>
while leftData.count > 0 && rightData.count > 0 {
if leftData[0] > rightData[0] {
result.append(rightData.first!)
rightData.remove(at: 0)
}else{
result.append(leftData.first!)
leftData.remove(at: 0)
}
}
while leftData.count > 0 {
result.append(leftData.first!)
leftData.remove(at: 0)
}
while rightData.count > 0 {
result.append(rightData.first!)
rightData.remove(at: 0)
}
return result
}

func devideData(_ array:Array<Int>)->Any {
if array.count < 2 {
return array
}
let middle = array.count/2
var left:Array<Int> = []
var right:Array<Int> = []
for i in 0...(array.count-1) {
if i < middle {
left.append(array[i])
}else{
right.append(array[i])
}
}
return mergeData(devideData(left),devideData(right))
}

let result = devideData(dataAry)
print("归并排序:",result)
return result
}

/// 快速排序
static func quickSort(_ data:Array<Int>)->Any {
let num = data.count - 1
if num < 1 {
return data
}

func swap(data: inout Array<Int>, i:Int, j:Int) {
let temp = data[i]
data[i] = data[j]
data[j] = temp
}
//挖坑法
func findPoint(result: inout Array<Int>, start:Int, end:Int)->Int {
let value = result[start]
var left = start
var right = end
while left < right {
while left < right && result[right] > value {
right -= 1
}
result[left] = result[right]
while left < right && result[left] <= value {
left += 1
}
result[right] = result[left]
}
result[left] = value
return left
}
//前后指针法
func findPoint2(result: inout Array<Int>, start:Int, end:Int)->Int {
//取队尾为桩
let value = result[end]
var i = start
var index = start
while i < end {
if result[i] < value {
swap(data: &result, i: i, j: index)
index += 1
}
i += 1
}
swap(data: &result, i: end, j: index)
return index

// //取队头为桩
// let pivot = result[start]
// var index = start + 1
// var i = index
// while i <= end {
// if result[i] < pivot {
// swap(data:&result, i:i, j:index)
// index += 1
// }
// i += 1
// }
// swap(data:&result,i:start,j:index-1)
// return index-1
}

func quickSortStart(_ data: inout Array<Int>, _ start:Int, _ end:Int)->Any {
if start < end {
let pivotIndex = findPoint(result: &data, start: start, end: end)
// let pivotIndex = findPoint2(result: &data, start: start, end: end)
data = quickSortStart(&data, start, pivotIndex-1) as! Array<Int>
data = quickSortStart(&data, pivotIndex+1, end) as! Array<Int>
}
return data
}

var dataAry:Array<Int> = data
let result = quickSortStart(&dataAry,0,num)
print("快速排序:",result)
return result


}

/// 堆排序
static func heapSort(_ data:Array<Int>)->Any {
var dataAry:Array<Int> = data
if dataAry.count < 2 {
return dataAry
}
var arrLength = data.count

func swap(data: inout Array<Int>, i:Int, j:Int) {
let temp = data[i]
data[i] = data[j]
data[j] = temp
}

func heapify(_ data: inout Array<Int>, _ i:Int) {
let left = 2*i + 1
let right = 2*i + 2
var largest = i
if left < arrLength && data[left] > data[largest] {
largest = left
}
if right < arrLength && data[right] > data[largest] {
largest = right
}
if largest != i {
swap(data: &data, i: i, j: largest)
heapify(&data, largest)
}
}

func buildHeap(_ data: inout Array<Int>) {
for i in (0..<data.count/2).reversed() {
heapify(&data, i)
}
}

buildHeap(&dataAry)
for i in (1..<dataAry.count).reversed() {
swap(data: &dataAry, i: 0, j: i)
arrLength -= 1
heapify(&dataAry, 0)
}

print("堆 排 序: \(dataAry)")
return dataAry
}

/// 计数排序
static func countSort(_ data:Array<Int>)->Any {
let dataAry:Array<Int> = data
if dataAry.count < 2 {
return dataAry
}
//计算最大最小值,得到临时数组的长度
var minValue = 0
var maxValue = 0
for item in dataAry {
minValue = min(minValue, item)
maxValue = max(maxValue, item)
}
let tempLen = maxValue - minValue + 1
//初始化临时数组
var temp:Array<Int> = [Int].init(repeating: 0, count: tempLen)
//源数组的值为key,出现次数为value存储到临时数组
for item in dataAry {
temp[item-minValue] += 1
}
//初始化结果数组
var result:Array<Int> = [Int].init(repeating: 0, count: dataAry.count)
var index = 0
for i in 0..<tempLen {
while temp[i] > 0 {
result[index] = i + minValue
index += 1
temp[i] -= 1
}
}
print("计数排序: \(result)")
return result
}

/// 桶排序
static func bucketSort(_ data:Array<Int>)->Any {
var dataAry:Array<Int> = data
let dataLength = dataAry.count

if dataLength < 2 {
return dataAry
}
//计算最大最小值,得到桶数量
var minValue = 0
var maxValue = 0
for item in dataAry {
minValue = min(minValue, item)
maxValue = max(maxValue, item)
}
//计算桶的数量
let bucketNum = (maxValue - minValue) / dataLength + 1
var bucketArr:Array<Array<Int>> = [Array].init(repeating: [Int](), count: bucketNum)
//将源数组元素放入各个桶中
for item in dataAry {
let num = (item - minValue)/dataLength
bucketArr[num].append(item)
}
//各个桶中元素进行排序(快排)
for i in 0..<bucketNum {
let bucketResult:Array<Int> = quickSort(bucketArr[i]) as! Array<Int>
//桶内数据排序时做了深拷贝,这里需要替换排序好的桶
bucketArr[i] = bucketResult
}
//将所有桶中元素取出
var index = 0
for item in bucketArr {
for i in 0..<item.count {
dataAry[index] = item[i]
index += 1
}
}
print(" 桶 排序: \(dataAry)")
return dataAry
}

/// 基数排序
static func radixSort(_ data:Array<Int>)->Any {
var dataAry:Array<Int> = data
if dataAry.count < 2 {
return dataAry
}

func digitsSort(_ data: inout Array<Int>, _ exp:Int)->Any {
// 存储本次排序结果的临时数组
var result:Array<Int> = Array.init(repeating: 0, count: data.count)
// 用于排序的桶,由于每一位的数字只能是[0-9),所以默认新建长度为10的数组
var bucket:Array<Int> = Array.init(repeating: 0, count: 10)
// 源数组每一项数据当前位数的值为key,出现次数为value存储到桶中
for item in data {
bucket[(item/exp)%10] += 1
}
// 这里修改后使得buckets[i]的值就是排序后该数据在源数组中应处的位置
for i in 1..<bucket.count {
bucket[i] += bucket[i-1]
}
for i in (0..<data.count).reversed() {
let num = (data[i]/exp)%10
result[bucket[num]-1] = data[i]
bucket[num] -= 1
}
for i in 0..<data.count {
data[i] = result[i]
}
return data
}

let maxValue:Int = { () -> Int in
var value = dataAry[0]
for item in dataAry {
value = max(item, value)
}
return value
}()
// exp:排序位数,各位1,十位1*10...
var exp = 1
while maxValue/exp > 0 {
dataAry = digitsSort(&dataAry, exp) as! Array<Int>
exp *= 10
}
print("基数排序: \(dataAry)")
return dataAry
}
}