example02.py 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  1. """
  2. 排序 - 冒泡排序、选择排序、归并排序、快速排序
  3. 冒泡排序 - O(n ** 2):两两比较,大的下沉
  4. 35, 97, 12, 68, 55, 73, 81, 40
  5. 35, 12, 68, 55, 73, 81, 40, [97]
  6. 12, 35, 55, 68, 73, 40, [81]
  7. 12, 35, 55, 68, 40, [73]
  8. ...
  9. 选择排序 - O(n ** 2):每次从剩下元素中选择最小
  10. -----------------------------------------
  11. 归并排序 - O(n * log_2 n) - 高级排序算法
  12. 35, 97, 12, 68, 55, 73, 81, 40
  13. [35, 97, 12, 68], [55, 73, 81, 40]
  14. [35, 97], [12, 68], [55, 73], [81, 40]
  15. [35], [97], [12], [68], [55], [73], [81], [40]
  16. [35, 97], [12, 68], [55, 73], [40, 81]
  17. [12, 35, 68, 97], [40, 55, 73, 81]
  18. [12, 35, 40, 55, 68, 73, 81, 97]
  19. -----------------------------------------
  20. 快速排序 - 以枢轴为界将列表中的元素划分为两个部分,左边都比枢轴小,右边都比枢轴大
  21. 35, 97, 12, 68, 55, 73, 81, 40
  22. 35, 12, [40], 68, 55, 73, 81, 97
  23. [12], 35, [40], 68, 55, 73, 81, [97]
  24. [12], 35, [40], 55, [68], 73, 81, [97]
  25. [12], 35, [40], 55, [68], 73, [81], [97]
  26. """
  27. class Person(object):
  28. """人"""
  29. def __init__(self, name, age):
  30. self.name = name
  31. self.age = age
  32. # def __gt__(self, other):
  33. # return self.name > other.name
  34. def __str__(self):
  35. return f'{self.name}: {self.age}'
  36. def __repr__(self):
  37. return self.__str__()
  38. def select_sort(origin_items, comp=lambda x, y: x < y):
  39. """简单选择排序"""
  40. items = origin_items[:]
  41. for i in range(len(items) - 1):
  42. min_index = i
  43. for j in range(i + 1, len(items)):
  44. if comp(items[j], items[min_index]):
  45. min_index = j
  46. items[i], items[min_index] = items[min_index], items[i]
  47. return items
  48. # 函数的设计要尽量做到无副作用(不影响调用者)
  49. # 9 1 2 3 4 5 6 7 8
  50. # 9 2 3 4 5 6 7 8 1
  51. # *前面的参数叫位置参数,传参时只需要对号入座即可
  52. # *后面的参数叫命名关键字参数,传参时必须给出参数名和参数值
  53. # *args - 可变参数 - 元组
  54. # **kwargs - 关键字参数 - 字典
  55. def bubble_sort(origin_items, *, comp=lambda x, y: x > y):
  56. """冒泡排序"""
  57. items = origin_items[:]
  58. for i in range(1, len(items)):
  59. swapped = False
  60. for j in range(i - 1, len(items) - i):
  61. if comp(items[j], items[j + 1]):
  62. items[j], items[j + 1] = items[j + 1], items[j]
  63. swapped = True
  64. if swapped:
  65. swapped = False
  66. for j in range(len(items) - i - 1, i - 1, -1):
  67. if comp(items[j - 1], items[j]):
  68. items[j], items[j - 1] = items[j - 1], items[j]
  69. swapped = True
  70. if not swapped:
  71. break
  72. return items
  73. def merge_sort(items, comp=lambda x, y: x <= y):
  74. """归并排序"""
  75. if len(items) < 2:
  76. return items[:]
  77. mid = len(items) // 2
  78. left = merge_sort(items[:mid], comp)
  79. right = merge_sort(items[mid:], comp)
  80. return merge(left, right, comp)
  81. def merge(items1, items2, comp=lambda x, y: x <= y):
  82. """合并(将两个有序列表合并成一个新的有序列表)"""
  83. items = []
  84. index1, index2 = 0, 0
  85. while index1 < len(items1) and index2 < len(items2):
  86. if comp(items1[index1], items2[index2]):
  87. items.append(items1[index1])
  88. index1 += 1
  89. else:
  90. items.append(items2[index2])
  91. index2 += 1
  92. items += items1[index1:]
  93. items += items2[index2:]
  94. return items
  95. def quick_sort(origin_items, comp=lambda x, y: x <= y):
  96. """快速排序"""
  97. items = origin_items[:]
  98. _quick_sort(items, 0, len(items) - 1, comp)
  99. return items
  100. def _quick_sort(items, start, end, comp):
  101. """递归调用划分和排序"""
  102. if start < end:
  103. pos = _partition(items, start, end, comp)
  104. _quick_sort(items, start, pos - 1, comp)
  105. _quick_sort(items, pos + 1, end, comp)
  106. def _partition(items, start, end, comp):
  107. """划分"""
  108. pivot = items[end]
  109. i = start - 1
  110. for j in range(start, end):
  111. if comp(items[j], pivot):
  112. i += 1
  113. items[i], items[j] = items[j], items[i]
  114. items[i + 1], items[end] = items[end], items[i + 1]
  115. return i + 1
  116. def main():
  117. """主函数"""
  118. items = [35, 97, 12, 68, 55, 73, 81, 40]
  119. # print(bubble_sort(items))
  120. # print(select_sort(items))
  121. # print(merge_sort(items))
  122. print(quick_sort(items))
  123. items2 = [
  124. Person('Wang', 25), Person('Luo', 39),
  125. Person('Zhang', 50), Person('He', 20)
  126. ]
  127. # print(bubble_sort(items2, comp=lambda p1, p2: p1.age > p2.age))
  128. # print(select_sort(items2, comp=lambda p1, p2: p1.name < p2.name))
  129. # print(merge_sort(items2, comp=lambda p1, p2: p1.age <= p2.age))
  130. print(quick_sort(items2, comp=lambda p1, p2: p1.age <= p2.age))
  131. items3 = ['apple', 'orange', 'watermelon', 'durian', 'pear']
  132. # print(bubble_sort(items3))
  133. # print(bubble_sort(items3, comp=lambda x, y: len(x) > len(y)))
  134. # print(merge_sort(items3))
  135. print(merge_sort(items3))
  136. if __name__ == '__main__':
  137. main()