| 42 | |
| 43 | """ |
| 44 | class Solution(object): |
| 45 | |
| 46 | def quickSort(self, unsorted_list): |
| 47 | """ |
| 48 | 每次都选一个基准点,大的放在右边,小的放在左边,等于的随便归到一个地方,不断拆分拆分。 |
| 49 | 这里直接选用[0],当然这种情况下往往会发生不理想的情况, |
| 50 | 不理想的情况表示每次恰好都是最小或最大,这样的结果会直接导致算法变为O(n^2). |
| 51 | """ |
| 52 | |
| 53 | if len(unsorted_list) <= 1: |
| 54 | return unsorted_list |
| 55 | |
| 56 | left = [] |
| 57 | right = [] |
| 58 | |
| 59 | meta = self._getMiddle(unsorted_list) |
| 60 | for i in unsorted_list[:meta] + unsorted_list[meta+1:]: |
| 61 | if i <= unsorted_list[meta]: |
| 62 | left.append(i) |
| 63 | continue |
| 64 | right.append(i) |
| 65 | |
| 66 | return self.quickSort(left) + [unsorted_list[meta]] + self.quickSort(right) |
| 67 | |
| 68 | def _getMiddle(self, unsorted_list): |
| 69 | """ |
| 70 | 返回快排所需的基准点, |
| 71 | 左右中中间选择一个。 |
| 72 | 若不足3位,选左。 |
| 73 | """ |
| 74 | if len(unsorted_list) < 3: |
| 75 | return 0 |
| 76 | |
| 77 | left = unsorted_list[0] |
| 78 | right = unsorted_list[-1] |
| 79 | middle = unsorted_list[len(unsorted_list) // 2] |
| 80 | l, r, m = [(0, left), (len(unsorted_list) - 1, right), (len(unsorted_list) // 2, middle)] |
| 81 | # 这里对比了自己写的merge sort 与内置的差距, |
| 82 | # 在有key的情况下差距非常大。 |
| 83 | return sorted([l, r, m], key=lambda x: x[1])[1][0] |
| 84 | |
| 85 | |
| 86 | def mergeSort(self, unsorted_list, key=None): |
| 87 | """ |
| 88 | 归并排序的基本思路是分治,把一个大问题分解成小问题。逐个解决小问题。 |
| 89 | 以长度的一半为基准点,将一个大列表分为两个小列表,一直分一直分,然后合并。 |
| 90 | 所以排序分为两步: |
| 91 | 第一步是分解,第二步是合并。 |
| 92 | """ |
| 93 | if len(unsorted_list) <= 1: |
| 94 | return unsorted_list |
| 95 | |
| 96 | break_point = len(unsorted_list) // 2 |
| 97 | |
| 98 | left = self.mergeSort(unsorted_list[:break_point]) |
| 99 | right = self.mergeSort(unsorted_list[break_point:]) |
| 100 | |
| 101 | return self._decomposeAndMerge(left, right, key=key) |
no outgoing calls
no test coverage detected