离上次更新blog过去四个月了, 感觉写blog跟写日记差不多,是需要耐心和坚持的。
这次更新两个排序算法,一个是面试官最爱考的快排,一个是比较简单的归并排序。
一,快速排序:
首先贴代码:
"""快速排序""" def quick_sort(list): len_of_list = len(list) if len_of_list <= 1: return list else: left_list = [] right_list = [] random_index = random.randint(len_of_list) value_temp = list[random_index] for i in range(len_of_list): if i != random_index: if list[i] <= value_temp: left_list.append(list[i]) else: right_list.append(list[i]) test_list = [] test_list.extend(left_list) test_list.append(value_temp) test_list.extend(right_list) label = 1 for i in range(len_of_list - 1): if list[i+1] < list[i]: label = 0 if label == 1: return test_list else: left_list = quick_sort(left_list) right_list = quick_sort(right_list) result_list = [] result_list.extend(left_list) result_list.append(value_temp) result_list.extend(right_list) return result_list
random.seed(123456) List1 = random.randint(-16, 16, size=16)
print(quick_sort(list(List1)))
运行结果如下:
[-16, -15, -12, -8, -6, -6, -6, -5, -5, -4, -1, 1, 2, 7, 8, 11]
我采用了递归的思路来实现快速排序。快排首先从列表中随机选取一个元素,保持元素的位置不动, 将比这个元素小的其他元素放入left_list,比这个元素大的其他元素放入right_list,从而将原问题拆分成了两个相同的子问题。然后再对left_list和right_list分别用相同的思路进行排序,直到left_list和right_list都有序。此时,将left_list和选出的元素以及right_list合并为一个有序列表并返回。在这个过程中需要考虑一些特殊情况,比如待排序的列表的长度小于等于1,那么在这种情况下就没有排序的必要,直接返回原来的列表就可以了。另外就是递归停止的条件是划分后的left_list和选出的元素以及right_list组成的test_list是否已经排好序,如果已经排好序,则停止递归直接返回,否则继续。在这里,其实可以选择分别判断left_list和right_list是否已经有序,如果已经有序则没有必要对已经有序的list继续递归排序,我这里的处理有一点粗糙,有一定可能存在冗余的运算。最后,快排的平均时间复杂度是O(n*logn), 最坏时间复杂度为O(n^2)。
二、归并排序
首先贴代码:
def merge_sort(list1, list2): len_of_list1 = len(list1) len_of_list2 =len(list2) index_1 = 0 index_2 = 0 result_list = [] if len_of_list1 == 0 and len_of_list2 ==0: return [] elif len_of_list1 == 0 and len_of_list2 != 0: return list2 elif len_of_list1 != 0 and len_of_list2 == 0: return list1 while True: if index_1 == len_of_list1 or index_2 == len_of_list2: break if list1[index_1] <= list2[index_2]: result_list.append(list1[index_1]) index_1 += 1 else: result_list.append(list2[index_2]) index_2 += 1 if index_1 == len_of_list1: for i in range(index_2, len_of_list2): result_list.append(list2[i]) return result_list else: for i in range(index_1, len_of_list1): result_list.append(list1[i]) return result_list
random.seed(123456) List1 = random.randint(-16, 16, size=16) List2 = random.randint(-50, 50, size=8)#设置随机数种子,保证每次运行结果一致 print(quick_sort(list(List1))) print(quick_sort(list(List2))) print(merge_sort(quick_sort(list(List1)), quick_sort(list(List2))))
运行结果如下:
[-16, -15, -12, -8, -6, -6, -6, -5, -5, -4, -1, 1, 2, 7, 8, 11]
[-36, -30, -16, -3, 0, 20, 25, 36]
[-36, -30, -16, -16, -15, -12, -8, -6, -6, -6, -5, -5, -4, -3, -1, 0, 1, 2, 7, 8, 11, 20, 25, 36]
归并排序的原理比较简单,输入为两个已经排好序的有序列表,然后合并为一个有序列表。数据结构与算法那本书里的图生动形象,我这里就不说废话了, 直接看下代码就可以了。