首页 > 编程语言 > 详细

Python实现 二分查找 冒泡排序 快速排序 插入排序 选择排序 堆排序 与归并排序

时间:2019-08-23 11:47:11      阅读:109      评论:0      收藏:0      [点我收藏+]
  1 # -*- encoding: utf-8 -*-
  2 import random
  3 
  4 
  5 class BinarySearch(object):
  6     @staticmethod
  7     def binary_search(order: list,  target: int, low: int, high: int):
  8         """ 列表长度校验,上下限校验, 列表排序校验(是否有序,升序还是降序) """
  9         # 认为是升序的 , 且参数合法的
 10         middle = (low + high) // 2
 11         if high == low:
 12             return middle + 1 if order[middle] <= target else middle
 13         elif high < low:
 14             return low
 15         else:
 16             if target == order[middle]:
 17                 return middle + 1
 18             elif target > order[middle]:
 19                 return BinarySearch.binary_search(order, target, middle + 1, high)
 20             else:
 21                 return BinarySearch.binary_search(order, target, low, middle - 1)
 22 
 23     @staticmethod
 24     def binary_search_in_loop(order: list, l: int, h: int, t: int):
 25         """ 列表长度校验,上下限校验, 列表排序校验(是否有序,升序还是降序) """
 26 
 27         # 认为是升序的 , 且参数合法的
 28         if t <= order[l]:
 29             return l
 30         if t >= order[h]:
 31             return h + 1
 32 
 33         while l <= h:
 34             middle = (l + h) // 2
 35             # 返回大于等于 t 的索引 ,往该索引 之前插入元素
 36             # 无论是 奇数个 还是 偶数个都会 折半为 偶数个
 37             if t == order[middle]:
 38                 return middle
 39             elif t > order[middle]:
 40                 if middle + 1 <= h and t < order[middle + 1]:
 41                     return middle + 1
 42                 l = middle + 1
 43             else:
 44                 if middle - 1 >= l and t > order[middle - 1]:
 45                     return middle
 46                 h = middle - 1
 47 
 48     @staticmethod
 49     def two_find(x, lis, start=0, end=None):
 50         if end is None:
 51             end = len(lis) - 1
 52         num = (end - start) // 2 + start
 53         if end > start:
 54             if lis[num] > x:
 55                 return BinarySearch.two_find(x, lis, start=start, end=num)
 56             elif lis[num] < x:
 57                 return BinarySearch.two_find(x, lis, start=num + 1, end=end)
 58             elif lis[num] == x:
 59                 return num
 60             elif lis[end] == x:
 61                 return end
 62         else:
 63             return None
 64 
 65 
 66 class BubbleSort(object):
 67 
 68     @staticmethod
 69     def bubble_sort_for(scrambl: list):
 70         list_size = len(scrambl)
 71         finish = False
 72         for i in range(list_size):
 73             if not finish:
 74                 finish = True
 75                 for j in range(list_size - i - 1):
 76                     if scrambl[j] > scrambl[j + 1]:
 77                         scrambl[j], scrambl[j + 1] = scrambl[j + 1], scrambl[j]
 78                         finish = False
 79             else:
 80                 break
 81         return scrambl
 82 
 83     @staticmethod
 84     def bubble_sort_while(scrambl: list):
 85         list_size = len(scrambl)
 86         finish = True
 87         while list_size > 1:
 88             if finish:
 89                 finish = False
 90                 for j in range(list_size - 1):
 91                     if scrambl[j] > scrambl[j + 1]:
 92                         scrambl[j], scrambl[j + 1] = scrambl[j + 1], scrambl[j]
 93                         finish = True
 94             else:
 95                 break
 96             list_size -= 1
 97         return scrambl
 98 
 99 
100 class QuickSort(object):
101     """
102         1-为了便于递归经常选择第一个(倒数第一个也可以)作为中心数据,
103           因为递归过程中递归范围是变动的,从而无法选择其他位置作为中心数据。
104         2-不能保证你最后交换的那个数,是小于等于左边的,这与基准数的位置有关。
105           比如2 1 4 9
106     """
107 
108     @staticmethod
109     def quick_sort(scrambl: list, low: int, high: int):
110         if low > high:
111             return
112         i = low
113         j = high
114         center = scrambl[low]
115         # criterion : n. (批评判断的)标准;准则;规范;准据
116 
117         ‘‘‘
118             【1】 j 向左找,找到小的停下;i 向右找,再碰到 j 之前找到大的;交换值后继续;直到 j 碰到 i,或者 i 碰到 j !
119             【2】 j 向左找,找到小的停下;i 向右找,直到碰到 j 还没找到大的,j 处为小的,将小的移到中心值处,将中心值放到小的处!
120             【3】 j 向左找,直到碰到 i 还没找到小的,i处只能小于等于中心值,因为i处大于中心值,则说明i向前走过,i,
121                   向前走过则应该发生交换,此时 将 i 处值换为中心值,将 i 处的值移动到 中心值处。
122             【4】 核心是 i 左边始终是小的 ,j 的右边始终是大的。
123         ‘‘‘
124 
125         while i < j:  # i != j
126             while i < j and scrambl[j] >= center:
127                 j -= 1
128 
129             while i < j and scrambl[i] <= center:
130                 i += 1
131 
132             if i < j:
133                 scrambl[i], scrambl[j] = scrambl[j], scrambl[i]
134 
135             print(scrambl)
136 
137         # 这种实现方式 最终 i 与 j 肯定位于同一位置。
138         scrambl[low] = scrambl[i]
139         scrambl[i] = center
140         QuickSort.quick_sort(scrambl, low, i - 1)
141         QuickSort.quick_sort(scrambl, i + 1, high)
142 
143     @staticmethod
144     def quick_sort2(scrambl: list, low: int, high: int):
145         i = low
146         j = high
147         center = scrambl[low]
148         ‘‘‘
149             【1】 j 向左找,找到小的;与 i 互换, i 向右找, 找到大的,与 j 互换; 此时 大的将小的重复的覆盖。
150                   继续,循环覆盖,直到 j 碰到 i,或者 i 碰到 j !
151             【2】 j 向左找,找到小的;i 向右找,直到碰到 j 还没找到大的,只好与 j 停于同一个位置,j 处为重复的小的,替换为中心数据
152             【3】 j 向左找,直到碰到 i 还没找到小的,i 处只能大于(重复的大值)等于中心值(没走过),如果小于中心值,
153                   则说明只能为重复的小值,这与 j 找不到小的矛盾。如果不是重复的小值,则说明i走过,走过则i处应为重复的大值。
154             【4】 核心是 i 左边始终是小的 ,j 的右边始终是大的。碰到处 即 i=j 即为中心值
155         ‘‘‘
156         while i < j:
157             while i < j and scrambl[j] >= center:
158                 j -= 1
159             if i < j:
160                 scrambl[i] = scrambl[j]
161                 i += 1
162 
163             while i < j and scrambl[i] <= center:
164                 i += 1
165             if i < j:
166                 scrambl[j] = scrambl[i]
167                 j -= 1
168 
169             print(scrambl)
170 
171         scrambl[i] = center
172 
173         if i - 1 > low:
174             QuickSort.quick_sort2(scrambl, low, i - 1)
175         if j + 1 < high:
176             QuickSort.quick_sort2(scrambl, i + 1, high)
177 
178         # 默认返回None
179 
180 
181 class InsertSort(object):
182     """
183         插入排序对于少量的数据它是一个有效的算法。
184         插入排序的工作方式像人手里的扑克牌一样。
185         开始时我们手里为空并且桌子上的牌面向下。
186         然后我们每次从桌上拿走一张牌并将它插入手里正确的位置。
187         为了把这种牌插入正确的位置,我们要从右到左将它和已在手中的牌进行比较。
188     """
189 
190     @staticmethod
191     def insert_sort_forward(scrambl: list):
192         list_size = len(scrambl)
193         for i in range(1, list_size):  # 一开始手中已经有 1 张牌, 手中的牌都是有序的
194             temp = scrambl[i]  # scrambl[i] :揭起的第 i 张牌
195             for j in range(0, i):  # range(0, i-1) : 手中的 第0张到第i-1张有序牌
196                 if scrambl[j] > temp:  # 正向比较
197                     while i > j:
198                         scrambl[i] = scrambl[i - 1]
199                         i -= 1
200                     scrambl[j] = temp
201                     break
202         return scrambl
203 
204     @staticmethod
205     def insert_sort_backforward(scrambl: list):
206         list_size = len(scrambl)
207         for i in range(1, list_size):
208             end = i - 1
209             temp = scrambl[end]
210 
211             while end >= 0 and scrambl[end] > temp:  # 反向比较
212                 scrambl[end + 1] = scrambl[end]
213                 end -= 1
214 
215             scrambl[end + 1] = temp
216         return scrambl
217 
218     @staticmethod
219     def binary_insert_sort(scrambl):
220         length = len(scrambl)
221         for i in range(1, length):
222             insert_position = BinarySearch.binary_search(scrambl, scrambl[i], 0, i-1)
223             if insert_position == i:
224                 continue
225             else:
226                 insert_value = scrambl[i]
227                 for j in range(i, insert_position, -1):
228                     scrambl[j] = scrambl[j - 1]
229                 scrambl[insert_position] = insert_value
230         return scrambl
231 
232     @staticmethod
233     def shell_sort(scrambl: list):
234         # 希尔排序算法仅仅适用于当线性表为顺序存储的情况, 指针 --> x --> y --> z --> w
235         # The array is divided into multiple subarrays as many as the increment value .
236         increment = len(scrambl) // 2
237         while increment >= 1:
238             for i in range(increment):
239                 for j in range(i + increment, len(scrambl), increment):
240                     inserter = scrambl[j]
241                     compare_index = j
242                     while compare_index >= increment and inserter < scrambl[compare_index - increment]:
243                         scrambl[compare_index] = scrambl[compare_index - increment]
244                         compare_index = compare_index - increment
245                     scrambl[compare_index] = inserter
246             increment //= 2
247         return scrambl
248 
249 
250 class ChooseSort(object):
251 
252     @staticmethod
253     def choose_sort(scrambl: list):
254         list_size = len(scrambl)
255         for i in range(list_size - 1):
256             min_value = scrambl[i]
257             min_index = None
258             for j in range(i + 1, list_size):
259                 if scrambl[j] < min_value:
260                     min_value = scrambl[j]
261                     min_index = j
262             if min_index:
263                 scrambl[i], scrambl[min_index] = scrambl[min_index], scrambl[i]
264         return scrambl
265 
266     @staticmethod
267     def choose_sort2(scrambl: list):
268         list_size = len(scrambl)
269         for i in range(list_size - 1):
270             min_index = i
271             for j in range(i + 1, list_size):
272                 if scrambl[j] < scrambl[min_index]:
273                     min_index = j
274             if min_index > i:
275                 scrambl[i], scrambl[min_index] = scrambl[min_index], scrambl[i]
276         return scrambl
277 
278 
279 class HeapSort(object):
280     # 完全二叉树可以用线性结构表示的树形结构!
281     @staticmethod
282     def heap_sort(scrambl: list):
283         length = len(scrambl)
284         if length < 2:
285             return scrambl
286         for i in range(length//2 - 1, -1, -1):      # shift up
287             HeapSort.adjust_heap(scrambl, i, length)
288 
289         for i in range(length - 1, -1, -1):         # shift down
290             scrambl[0], scrambl[i] = scrambl[i], scrambl[0]
291             HeapSort.adjust_heap(scrambl, 0, i)
292         return scrambl
293 
294     @staticmethod
295     def adjust_heap(scrambl: list, father: int, length: int):
296         lchild = father * 2 + 1
297         rchild = father * 2 + 2
298         maxer = father
299 
300         if rchild < length and scrambl[rchild] > scrambl[maxer]:
301             maxer = rchild
302 
303         if lchild < length and scrambl[lchild] > scrambl[maxer]:
304             maxer = lchild
305 
306         if maxer != father:
307             scrambl[father], scrambl[maxer] = scrambl[maxer], scrambl[father]
308             HeapSort.adjust_heap(scrambl, maxer, length)
309 
310 
311 class MergeSort(object):
312     """
313         归并排序(MERGE-SORT)是建立在归并操作上的一种有效的排序算法,
314         该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。
315         将已有序的子序列合并,得到完全有序的序列;即先使每个子序列有序,
316         再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
317     """
318 
319     @staticmethod
320     def merge_sort(scrambl: list, low_start: int, low_end: int, high_start: int, high_end: int):
321         # tmp = [None for i in range(len(scrambl))]
322         # ps: list() will create a empty list, that means you can not index.
323         tmp = [None] * len(scrambl)  # * 对非字面值是浅拷贝
324         ls = index = low_start
325         while low_start <= low_end and high_start <= high_end:
326             if scrambl[low_start] <= scrambl[high_start]:
327                 tmp[index] = scrambl[low_start]
328                 low_start += 1
329                 index += 1
330             else:
331                 tmp[index] = scrambl[high_start]
332                 high_start += 1
333                 index += 1
334         while low_start <= low_end:
335             tmp[index] = scrambl[low_start]
336             low_start += 1
337             index += 1
338         while high_start <= high_end:
339             tmp[index] = scrambl[high_start]
340             high_start += 1
341             index += 1
342         while ls <= high_end:
343             scrambl[ls] = tmp[ls]
344             ls += 1
345 
346     @staticmethod
347     def divide(scrambl: list, low: int, high: int):
348         if low < high:
349             mid = (low + high) // 2
350             MergeSort.divide(scrambl, low, mid)
351             MergeSort.divide(scrambl, mid + 1, high)
352             MergeSort.merge_sort(scrambl, low, mid, mid + 1, high)
353 
354 
355 if __name__ == "__main__":
356     unorder = [random.randint(0, 10) for i in range(10)]
357     print(unorder)
358     """
359     print(BubbleSort.bubble_sort_for(unorder))
360     print(BubbleSort.bubble_sort_while(unorder))
361     a = [3, 9, 6, 1, 5, 4, 0, 8, 7, 2]
362     QuickSort.quick_sort(a, 0, 9)
363     print(a)
364     b = [3, 9, 6, 1, 5, 4, 0, 8, 7, 2]
365     QuickSort.quick_sort2(b, 0, 9)
366     print(b)
367     c = [3, 9, 6, 1, 5, 4, 0, 8, 7, 2]
368     print(InsertSort.insert_sort_forward(c))
369     d = [3, 9, 6, 1, 5, 4, 0, 8, 7, 2]
370     print(ChooseSort.choose_sort2(d))
371     e = [2, 4, 6, 8]
372     print(BubbleSort.bubble_sort_for([4, 3, 5, 2]))
373     MergeSort.divide(unorder, 0, len(unorder) - 1)
374     print(HeapSort.heap_sort(unorder))
375     for i in range(0, 11):                 # 0  1  2  3  4  5
376         print(i, BinarySearch.binary_search([1, 3, 4, 6, 8, 9], i, 0, 5))
377     """
378     print(InsertSort.binary_insert_sort(unorder))
379 
380 
381 # 基本数据结构 --> 高级数据结构 --> 基础算法 --> 高级算法 --> 机器学习算法
382 # chunk it up   |    Deliberate Practicing  |  FeedBack

 

Python实现 二分查找 冒泡排序 快速排序 插入排序 选择排序 堆排序 与归并排序

原文:https://www.cnblogs.com/holyzing/p/11398814.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!