Skip to content

Commit 2dfdcc4

Browse files
author
ray
committed
80%
almost finished
1 parent 9b9a428 commit 2dfdcc4

File tree

4 files changed

+167
-51
lines changed

4 files changed

+167
-51
lines changed

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/inspectionProfiles/profiles_settings.xml

Lines changed: 7 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

.idea/workspace.xml

Lines changed: 22 additions & 21 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 126 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,34 @@
1+
# -*- coding: utf-8 -*-
2+
13
# 循环不变性的三个性质:初始化/保持/终止
24
# 分治方法-将原始问题划分成n个小规模,且结构与原问题相似的自问题-递归
35
# 排序算法一般不超过下面这11种情况
4-
#1 Simple sorts
6+
# 1 Simple sorts
57
# 1.1 Insertion sort(插入排序)
68
# 1.2 Selection sort(选择排序)
79
#
8-
#2 Efficient sorts
10+
# 2 Efficient sorts
911
# 2.1 Merge sort (归并排序)
1012
# 2.2 Heapsort (堆排序)
1113
# 2.3 Quicksort (快速排序)
1214
#
13-
#3 Bubble sort and variants
15+
# 3 Bubble sort and variants
1416
# 3.1 Bubble sort (冒泡排序)
1517
# 3.2 Shell sort (希尔排序)
1618
# 3.3 Comb sort (梳排序)
1719
#
18-
#4 Distribution sort
20+
# 4 Distribution sort
1921
# 4.1 Counting sort(计数排序)
2022
# 4.2 Bucket sort(桶排序)
2123
# 4.3 Radix sort(基数排序)
2224
#########################################################################################
2325

2426
if __name__ == '__main__':
27+
from collections import defaultdict
28+
import math
2529
A = [4, 9, 1, 13, 34, 26, 10, 7, 4]
2630

31+
2732
# 1.1,插入排序
2833
# 算法流程:遍历把每个元素,按照这个元素前面的数组中,根据大小决定的位置,插入该元素
2934
# 最好:已经排好顺序的集合,这样只需要线性时间即遍历一次集合,每次只需要比较当前元素与前一个元素的大小问题,时间复杂度O(n)
@@ -35,11 +40,13 @@ def insert_sort(array):
3540
j = i
3641
while j > 0 and array[j] < array[j - 1]: # 升序
3742
# print(array)
38-
tmp = array[j-1]
39-
array[j-1] = array[j]
43+
tmp = array[j - 1]
44+
array[j - 1] = array[j]
4045
array[j] = tmp
4146
j -= 1
4247
return array
48+
49+
4350
# insert_sort(A)
4451

4552

@@ -48,22 +55,22 @@ def insert_sort(array):
4855
# 算法流程:将数组分为两部分,一部分是已经排好顺序的,另一部分是未排序的。每次找数组后半部分中最小的一个元素排到前面的序列
4956
# 选择排序最坏,最好,平均情况都是O(n^2).
5057

58+
59+
5160
def select_sort(array):
52-
n=len(array)
61+
n = len(array)
5362
for i in range(n):
54-
iMin = i
55-
for j in range(i+1, n):
56-
if array[iMin] > array[j]: #不断替换最小的索引
57-
iMin = j
58-
63+
i_min = i
64+
for j in range(i + 1, n):
65+
if array[i_min] > array[j]: # 不断替换最小的索引
66+
i_min = j
5967
tmp = array[i]
60-
array[i] = array[iMin]
61-
array[iMin] = tmp
62-
68+
array[i] = array[i_min]
69+
array[i_min] = tmp
6370
return array
6471

6572

66-
#select_sort(A)
73+
# select_sort(A)
6774

6875

6976
# 插入排序与选择排序的区别
@@ -82,26 +89,28 @@ def select_sort(array):
8289
# 算法:是一种基于“分治”策略的一种算法。
8390
# 归并排序算法是典型的分治算法,对于规模较大的问题,可以分解成若干容易求解的简单的问题,最后把解合并构成初始问题的解
8491

92+
93+
8594
def merge_sort(array):
8695
if len(array) <= 1:
8796
return array
8897
mid = int(len(array) / 2)
8998
left = merge_sort(array[:mid])
90-
right = merge_sort(array[mid:]) #先拆分,直到最小单元
99+
right = merge_sort(array[mid:]) # 先拆分,直到最小单元
91100
result = []
92-
93101
while len(left) > 0 and len(right) > 0:
94102
if left[0] > right[0]:
95103
result.append(right.pop(0))
96104
else:
97105
result.append(left.pop(0))
98106
if len(left) > 0:
99-
result.extend(merge_sort(left)) #剩下的列表全部添加到result中
107+
result.extend(merge_sort(left)) # 剩下的列表全部添加到result中
100108
else:
101109
result.extend(merge_sort(right))
102110
return result
103111

104-
#print(merge_sort(A))
112+
113+
# print(merge_sort(A))
105114

106115
# 2.2, 堆排序
107116
# 算法:是数据结构-堆,堆排序是选择排序种类的一部分。它的提升是用到了对数时间优先队列(即堆)而不是线性时间搜索。
@@ -111,7 +120,7 @@ def merge_sort(array):
111120
# 用根元素与最后一个元素交换位置,将根元素从堆中移除,堆大小减小1。
112121
# 修复堆,回到上一步,直到堆中不剩元素。
113122

114-
#def heap_sort(array):
123+
# def heap_sort(array):
115124

116125

117126
# 2.3, 快速排序
@@ -123,18 +132,21 @@ def merge_sort(array):
123132
# 冒泡排序效率非常低,效率还不如插入排序。数据量大时效率低,对于顺序颠倒的序列效率最低。
124133
# 算法流程:简单概括就是每次找到序列中最大或最小的元素排到最后面去,循环知道每个元素都处于正确位置。
125134

135+
136+
126137
def bubble_sort(array):
127-
n=len(array)
138+
n = len(array)
128139
for i in range(n):
129-
for j in range(n-1):
130-
if array[j] > array[j+1]:
131-
tmp = array[j+1]
132-
array[j+1] = array[j]
140+
for j in range(n - 1):
141+
if array[j] > array[j + 1]:
142+
tmp = array[j + 1]
143+
array[j + 1] = array[j]
133144
array[j] = tmp
134145

135-
return array
146+
return array
147+
136148

137-
#print(bubble_sort(A))
149+
# print(bubble_sort(A))
138150

139151
# 3.2 希尔排序
140152
# 希尔排序是in-place算法,但不是稳定的,其实质就是分组插入排序
@@ -145,15 +157,99 @@ def bubble_sort(array):
145157
# 因为直接插入排序在元素基本有序的情况下(接近最好情况),效率是很高的,因此希尔排序在时间效率上比前两种方法有较大提高。
146158

147159

160+
148161
def shell_sort(array):
149-
gap = len(array)/2
162+
n = len(array)
163+
gap = n // 2
150164
while gap > 0:
165+
for i in range(gap, n):
166+
j = i
167+
while j >= gap and array[j] < array[j - gap]:
168+
tmp = array[j - gap]
169+
array[j - gap] = array[j]
170+
array[j] = tmp
171+
j -= gap
172+
gap //= 2
173+
return array
174+
151175

176+
# print("shell:"+ str(shell_sort(A)))
152177

153178

179+
# 3.3 梳排序
180+
# 它是冒泡排序的一种变体,
181+
# 就像希尔排序是利用一个间隔值来分组,然后对每个分组进行插入排序一样
182+
# 梳排序是先分组,然后对每个分组进行冒泡排序,只不过梳排序每次取间隔为n/1.3
154183

155-
gap/=2
184+
185+
def comb_sort(array):
186+
gap = len(array)
187+
swaps = True
188+
while gap > 1 or swaps:
189+
gap = max(1, int(gap // 1.25)) # or 1.3,控制着速率
190+
swaps = False
191+
for i in range(len(array) - gap):
192+
j = i + gap
193+
if array[i] > array[j]:
194+
array[i], array[j] = array[j], array[i]
195+
swaps = True
196+
return array
197+
198+
199+
# print("comb_sort:"+ str(comb_sort(A)))
200+
201+
202+
# 4.1 计数排序
203+
# 对数组A进行计数排序,需要知道其最大最小值以确定数组范围
204+
# 并且需要一个额外的数组C,其中第i个元素是待排序数组A中值等于i的元素的个数
205+
# 然后根据数组C来将A中的元素排到正确的位置。
206+
207+
208+
# from collections import defaultdict
209+
def counting_sort(array, mn, mx): # 入参需要排序的数组中的最小值和最大值
210+
result = []
211+
count = defaultdict(int)
212+
for i in array:
213+
count[i] += 1
214+
for j in range(mn, mx + 1):
215+
result += [j] * count[j] # 返回 n个[j],如[3]*5 = [3,3,3,3,3], [3]*0 = []
216+
return result
156217

157218

219+
# print("counting_sort:" + str(counting_sort(A, 1, 26)))
158220

159221

222+
# 4.2 桶排序
223+
# 算法步骤:
224+
# 桶排序假设待排序的一组数统一的分布在一个范围中,并将这一范围划分成几个子范围,也就是桶。
225+
# 将待排序的一组数,分档规入这些子桶。并将桶中的数据进行排序。
226+
# 将各个桶中的数据有序的合并起来。
227+
# 所以,桶排序重点在于分组的映射函数
228+
229+
230+
231+
# 4.3 基数排序
232+
# 算法步骤:
233+
# 基数排序分为:最低位优先(Least Significant Digit first)法,简称LSD法,最高位优先(Most significant digital)法,简称MSD法;
234+
# LSD就是先排个位,然后拍十位...; MSD即为反过来的逻辑但是解法不同
235+
236+
# 4.3.1 LSD
237+
238+
# import math
239+
240+
241+
242+
def radix_sort(array, radix=10):
243+
k = int(math.ceil(math.log(max(array), radix))) # radix为底的log(max(array)),来计算有几位数
244+
bucket = [[] for i in range(radix)] # 分桶
245+
for i in range(1, k + 1):
246+
for j in array:
247+
bucket[int(j / (radix**(i - 1)) % (radix**i))].append(j) # 结合计数排序,% 相当于 mod 求模
248+
print(bucket)
249+
del array[:]
250+
for z in bucket:
251+
array += z
252+
del z[:]
253+
return array
254+
255+
# print("radix_sort:" + str(radix_sort(A)))

0 commit comments

Comments
 (0)