python经典算法代码_十大经典算法 Python实现

使用场景:

1,空间复杂度 越低越好、n值较大:

堆排序  O(nlog2n)  O(1)

2,无空间复杂度要求、n值较大:

桶排序  O(n+k)    O(n+k)

经典排序算法图解:

926003-20190313224706139-608920958.png

经典排序算法的复杂度:

926003-20190313224802480-901260053.png

大类一(比较排序法):

1、冒泡排序(Bubble Sort)【前后比较-交换】

926003-20190313224958600-1838129265.gif

python代码实现:

copycode.gif

1 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44]

2 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64] # 正确排序

3

4 while 1:

5 state = 0 # 假设本次循环没有改变

6 for i in range(len(d0) - 1):

7 if d0[i] > d0[i + 1]:

8 d0[i], d0[i + 1] = d0[i + 1], d0[i]

9 state = 1 # 有数值交换,那么状态值置1

10 if not state: # 如果没有数值交换,那么就跳出

11 break

12

13 print(d0)

14 print(d0_out)

copycode.gif

2、选择排序(Selection Sort)【选择最小的数据放在前面】

926003-20190313225103638-255097344.gif

python代码实现:

copycode.gif

1 def select_sort(data):

2 d1 = []

3 while len(data):

4 min = [0, data[0]]

5 for i in range(len(data)):

6 if min[1] > data[i]:

7 min = [i, data[i]]

8 del data[min[0]] # 找到剩余部分的最小值,并且从原数组中删除

9 d1.append(min[1]) # 在新数组中添加

10 return d1

11

12 if __name__ == "__main__":

13 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44] # 原始乱序

14 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64] # 正确排序

15 d1 = select_sort(d0)

16 print(d1)

17 print(d0_out)

copycode.gif

3、插入排序(Insertion Sort)【逐个插入到前面的有序数中】

926003-20190313225201423-426936988.gif

直接插入排序-python实现:

copycode.gif

1 def direct_insertion_sort(d): # 直接插入排序,因为要用到后面的希尔排序,所以转成function

2 d1 = [d[0]]

3 for i in d[1:]:

4 state = 1

5 for j in range(len(d1) - 1, -1, -1):

6 if i >= d1[j]:

7 d1.insert(j + 1, i) # 将元素插入数组

8 state = 0

9 break

10 if state:

11 d1.insert(0, i)

12 return d1

13

14

15 if __name__ == "__main__":

16 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44] # 原始乱序

17 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64] # 正确排序

18 d1 = direct_insertion_sort(d0)

19 print(d1)

20 print(d0_out)

copycode.gif

折半插入排序-python实现:

copycode.gif

1 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44] # 原始乱序

2 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64] # 正确排序

3

4 d1 = [d0[0]]

5 del d0[0]

6

7 for i in d0:

8 index_now = [0, len(d1)]

9 while 1:

10 index = index_now[0] + int((index_now[1] - index_now[0]) / 2)

11 if i == d1[index]:

12 d1.insert(index+1,i)

13 break

14 elif index in index_now: # 如果更新的index值在index_now中存在(也有可能是边界),那么就表明无法继续更新

15 d1.insert(index+1,i)

16 break

17 elif i > d1[index]:

18 index_now[0] = index

19 elif i < d1[index]:

20 index_now[1] = index

21

22 print(d1)

23 print(d0_out)

copycode.gif

4、希尔排序(Shell Sort)【从大范围到小范围进行比较-交换】类似冒泡和插入的联合

926003-20190313225335181-41847049.gif

python代码实现:

copycode.gif

1 def direct_insertion_sort(d): # 直接插入排序,因为要用到后面的希尔排序,所以转成function

2 d1 = [d[0]]

3 for i in d[1:]:

4 state = 1

5 for j in range(len(d1) - 1, -1, -1):

6 if i >= d1[j]:

7 d1.insert(j + 1, i) # 将元素插入数组

8 state = 0

9 break

10 if state:

11 d1.insert(0, i)

12 return d1

13

14

15 def shell_sort(d): # d 为乱序数组,l为初始增量,其中l

16 length = int(len(d) / 2) # 10

17 num = int(len(d) / length) # 2

18 while 1:

19

20 for i in range(length):

21 d_mid = []

22 for j in range(num):

23 d_mid.append(d[i + j * length])

24 d_mid = direct_insertion_sort(d_mid)

25 for j in range(num):

26 d[i + j * length] = d_mid[j]

27 # print(d)

28 length = int(length / 2)

29 if length == 0:

30 return d

31 break

32 # print('length:',length)

33 num = int(len(d) / length)

34

35

36 if __name__ == "__main__":

37 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44] # 原始乱序

38 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64] # 正确排序

39 d1 = shell_sort(d0)

40 print(d1)

41 print(d0_out)

copycode.gif

5、归并排序(Merge Sort)【分治法-2-4-8插入排序】

926003-20190313225446367-1508151717.gif

python代码实现(这个地方是由大往小进行递归):

copycode.gif

1 # 归并排序,还有些问题。其中有些细节需要重新理解

2 # 也是递归问题

3 def merge_sort(data): # 分治发的典型应用,大问题拆分成小问题,逐个击破,之后将结果合并

4 half_index = int(len(data) / 2) # 将数组拆分

5

6 d0 = data[:half_index]

7 d1 = data[half_index:]

8

9 if len(d0) > 1:

10 d0 = merge_sort(d0)

11

12 if len(d1) > 1:

13 d1 = merge_sort(d1)

14

15 index = 0

16 for i in range(len(d1)):

17 state = 1

18 for j in range(index, len(d0)):

19 if d1[i] < d0[j]:

20 state = 0

21 index = j + 1

22 d0.insert(j, d1[i])

23 break

24 if state == 1: # 如果大于d0这个队列的所有值,那么直接extend所有数据

25 d0.extend(d1[i:])

26 break

27 return d0

28

29

30 if __name__ == "__main__":

31 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44] # 原始乱序

32 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64] # 正确排序

33 d1 = merge_sort(d0)

34 print(d1)

35 print(d0_out)

copycode.gif

python代码实现(由小扩展到大的子序列):

copycode.gif

1

2 def list_sort(d0, d1): # 基元组往大扩展

3 index = 0

4 for i in range(len(d1)): # 遍历d1数组

5 state = 1

6 for j in range(index, len(d0)): # 遍历d0数组

7 if d0[j] > d1[i]:

8 state = 0

9 index = j + 1

10 d0.insert(j, d1[i])

11 break

12 if state == 1: # 如果大于d0这个队列的所有值,那么直接extend所有数据

13 d0.extend(d1[i:])

14 break

15 return d0

16

17

18 def merge_sort(data):

19 d0 = [[x] for x in data]

20 while len(d0) != 1: # 循环条件

21 length = len(d0)

22 half = int(length/2) # 除2的整数部分

23 quo = length%2 # 除2的商

24 d0_mid = []

25 for i in range(half):

26 d0_mid.append(list_sort(d0[i*2], d0[i*2+1]))

27 if quo:

28 d0_mid.append(d0[-1])

29 d0 = d0_mid

30

31 return d0[0]

32

33

34

35 if __name__ == "__main__":

36 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44] # 原始乱序

37 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64] # 正确排序

38 d1 = merge_sort(d0)

39 print(d1)

40 print(d0_out)

copycode.gif

6、快速排序(Quick Sort)【选取一个基准值,小数在左大数在在右】

926003-20190313225544009-2058813586.gif

python代码实现:

copycode.gif

1 # import sys

2 # sys.setrecursionlimit(1000000)

3

4 def quick_sort(data):

5 d = [[], [], []]

6 d_pivot = data[-1] # 因为是乱序数组,所以第几个都是可以的,理论上是一样的

7 for i in data:

8 if i < d_pivot: # 小于基准值的放在前

9 d[0].append(i)

10 elif i > d_pivot: # 大于基准值的放在后

11 d[2].append(i)

12 else: # 等于基准值的放在中间

13 d[1].append(i)

14

15 # print(d[0], d[1], d[2])

16 if len(d[0]) > 1: # 大于基准值的子数组,递归

17 d[0] = quick_sort(d[0])

18

19 if len(d[2]) > 1: # 小于基准值的子数组,递归

20 d[2] = quick_sort(d[2])

21

22 d[0].extend(d[1])

23 d[0].extend(d[2])

24 return d[0]

25

26

27 if __name__ == "__main__":

28 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44] # 原始乱序

29 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64] # 正确排序

30 d1 = quick_sort(d0)

31 print(d1)

32 print(d0_out)

copycode.gif

7、堆排序(Heap Sort)【利用最大堆和最小堆的特性】

926003-20190313225630378-1298399765.gif

python代码实现:

copycode.gif

1 d0 = [99, 5, 36, 7, 22, 17, 46, 12, 2, 19, 25, 28, 1, 92]

2

3

4 def sort_max(data): # 直接冒泡一下吧,小到大

5 for i in range(len(data) - 1):

6 for j in range(len(data) - 1):

7 if data[j] > data[j + 1]:

8 data[j], data[j + 1] = data[j + 1], data[j]

9 return data

10

11 def heap_min(data,type):

12 index = 0

13 if not type:

14 for i in range(len(data[1:])):

15 if data[index] > data[i+1]:

16 index = i+1

17 data[0],data[index] = data[index],data[0]

18 return data

19 else:

20 for i in range(len(data[1:])):

21 if data[index] < data[i+1]:

22 index = i+1

23 data[0],data[index] = data[index],data[0]

24 return data

25

26

27 # d0 = [3,2,1,10,3]

28 # print(heap_min(d0,1))

29 # print(heap_min(d0,0))

30

31 import numpy as np

32

33

34 def heap_adj(data, type): # data 原始堆,type=1最大堆,type=0最小堆

35 length = len(data)

36 floor = int(np.log2(length))

37 for i in range(floor, 0, -1): # 3(7 6 5 4)-2(3 2)-1(1)

38 for j in range(2 ** floor - 1, 2 ** (floor - i) - 1, -1):

39 # print(i,j) # j-1 为当前父节点

40 d_mid = [data[j - 1]] # j = 7,j-1 =6 index

41 if j * 2 <= length: # 14

42 d_mid.append(data[j * 2 - 1])

43 if j * 2 + 1 <= length:

44 d_mid.append(data[j * 2])

45

46 d_mid = heap_min(d_mid, type)

47

48 if len(d_mid) == 2:

49 data[j - 1], data[j * 2 - 1] = d_mid[0], d_mid[1]

50 elif len(d_mid) == 3:

51 data[j - 1], data[j * 2 - 1], data[j * 2] = d_mid[0], d_mid[1], d_mid[2]

52 return data

53

54 d1 = []

55 for i in range(len(d0)):

56 data = heap_adj(d0, 0)

57 d1.append(d0[0])

58 del d0[0]

59

60

61 print(d1)

copycode.gif

大类二(非比较排序法):

8、计数排序(Counting Sort)【字典计数-还原】

926003-20190313225936359-1532049862.gif

python代码实现:

copycode.gif

1 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44]

2 d0_out = [2, 2, 2, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 7, 9, 12, 15, 44, 45, 54, 64]

3

4 d_max = 0

5 d_min = 0

6 for i in d0:

7 if d_max

8 d_max = i

9 if d_min>i:

10 d_min = i

11

12 d1 = {}

13 for i in d0:

14 if i in d1.keys():

15 d1[i] += 1

16 else:

17 d1[i] = 1

18

19 d2 = []

20 for i in range(d_min,d_max+1):

21 if i in d1.keys():

22 for j in range(d1[i]):

23 d2.append(i)

24

25 print(d2)

copycode.gif

9、桶排序(Bucket Sort)【链表】

926003-20190313230129692-587105734.png

python代码实现:

copycode.gif

1 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44]

2

3 d1 = [[] for x in range(10)]

4 for i in d0:

5 d1[int(i/10)].append(i)

6

7 # print(d1)

8

9

10 for i in range(len(d1)):

11 if d1[i] != []:

12 d2 = [[] for x in range(10)]

13 for j in d1[i]:

14 d2[j%10].append(j)

15 d1[i] = d2

16

17 # print(d1)

18

19 d3 = []

20 for i in d1:

21 if i:

22 for j in i:

23 if j:

24 for k in j:

25 if k:

26 d3.append(k)

27 print(d3)

copycode.gif

10、基数排序(Radix Sort)

926003-20190313230236995-492741747.gif

python代码实现:

copycode.gif

1 d0 = [2, 15, 5, 9, 7, 6, 4, 12, 5, 4, 2, 64, 5, 6, 4, 2, 3, 54, 45, 4, 44]

2

3 d1 = [[] for x in range(10)]

4

5 # 第一次 最小位次排序

6 for i in d0:

7 d1[i % 10].append(i)

8

9 print(d1)

10

11 d0_1 = []

12 for i in d1:

13 if i:

14 for j in i:

15 d0_1.append(j)

16 print(d0_1)

17

18 # 第二次 次低位排序

19 d2 = [[] for x in range(10)]

20 for i in d0_1:

21 d2[int(i/10)].append(i)

22 print(d2)

23

24 d0_2 = []

25 for i in d2:

26 if i:

27 for j in i:

28 d0_2.append(j)

29 print(d0_2)

copycode.gif

出自 https://www.cnblogs.com/Mufasa/p/10527387.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值