标签:情况下 通过 return src color 地方 sel wap 关键字
快速排序的基本思想:通过一趟排序将待排记录分隔成独立的两部分,其中一部分记录的关键字均比另一部分的关键字小,则可分别对这两部分记录继续进行递归排序,以达到整个序列有序。
示例:
pivot:中间枢纽 ( 5)
portitiom:分区
Two points:两个指针 ( i:左->右 j:左<-右)
def _quick_sorted(nums: list) -> list: if len(nums) <= 1: return nums pivot = nums[0] #pivot左右边分别调用quick_sort left_nums = _quick_sorted([x for x in nums[1:] if x < pivot]) #找左半边比枢纽小的 right_nums = _quick_sorted([x for x in nums[1:] if x >= pivot]) #找右半边比枢纽大的 return left_nums + [pivot] + right_nums def quick_sorted(nums: list, reverse=False)-> list: """Quick Sort""" start = time.time() nums = _quick_sorted(nums) if reverse: nums = nums[::-1] t = time.time() - start return nums, len(nums), t lis = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0] lis = quick_sorted(lis, reverse=False) print(lis) #输出结果 ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 10, 0.0)
def quick_sort(nums): # 封装一层的目的是方便用户调用 def qsort(lst, begin, end): if begin >= end: return i = begin key = lst[begin] for j in range(begin+1, end+1): if lst[j] < key: i += 1 lst[i], lst[j] = lst[j], lst[i] lst[begin], lst[i] = lst[i], lst[begin] qsort(lst, begin, i-1) qsort(lst,i+1,end) qsort(nums, 0, len(nums)-1)
前面我们每次选取pivot_key的都是子序列的第一个元素,也就是lis[low],这就比较看运气。运气好时,该值处于整个序列的靠近中间值,则构造的树比较平衡,运气比较差,处于最大或最小位置附近则构造的树接近斜树。
为了保证pivot_key选取的尽可能适中,采取选取序列左中右三个特殊位置的值中,处于中间值的那个数为pivot_key,通常会比直接用lis[low]要好一点。在代码中,在原来的pivot_key = lis[low]这一行前面增加下面的代码:
m = low + int((high-low)/2) if lis[low] > lis[high]: self.swap(low, high) if lis[m] > lis[high]: self.swap(high, m) if lis[m] > lis[low]: self.swap(m, low)
如果觉得这样还不够好,还可以将整个序列先划分为3部分,每一部分求出个pivot_key,再对3个pivot_key再做一次上面的比较得出最终的pivot_key。这时的pivot_key应该很大概率是一个比较靠谱的值。
原来的代码中pivot_key这个记录总是再不断的交换中,其实这是没必要的,完全可以将它暂存在某个临时变量中,如下所示:
def partition(self, low, high): lis = self.r m = low + int((high-low)/2) if lis[low] > lis[high]: self.swap(low, high) if lis[m] > lis[high]: self.swap(high, m) if lis[m] > lis[low]: self.swap(m, low) pivot_key = lis[low] # temp暂存pivot_key的值 temp = pivot_key while low < high: while low < high and lis[high] >= pivot_key: high -= 1 # 直接替换,而不交换了 lis[low] = lis[high] while low < high and lis[low] <= pivot_key: low += 1 lis[high] = lis[low] lis[low] = temp return low
快速排序算法的递归操作在进行大量数据排序时,其开销能被接受,速度较快。但进行小数组排序时则不如直接插入排序来得快,也就是杀鸡用牛刀,未必就比菜刀来得快。
因此,一种很朴素的做法就是根据数据的多少,做个使用哪种算法的选择而已,如下改写qsort方法:
def qsort(self, low, high): """根据序列长短,选择使用快速排序还是简单插入排序""" # 7是一个经验值,可根据实际情况自行决定该数值。 MAX_LENGTH = 7 if high-low < MAX_LENGTH: if low < high: pivot = self.partition(low, high) self.qsort(low, pivot - 1) self.qsort(pivot + 1, high) else: # insert_sort方法是我们前面写过的简单插入排序算法 self.insert_sort()
可以采用尾递归的方式对整个算法的递归操作进行优化,改写qsort方法如下:
def qsort(self, low, high): """根据序列长短,选择使用快速排序还是简单插入排序""" # 7是一个经验值,可根据实际情况自行决定该数值。 MAX_LENGTH = 7 if high-low < MAX_LENGTH: # 改用while循环 while low < high: pivot = self.partition(low, high) self.qsort(low, pivot - 1) # 采用了尾递归的方式 low = pivot + 1 else: # insert_sort方法是我们前面写过的简单插入排序算法 self.insert_sort()
标签:情况下 通过 return src color 地方 sel wap 关键字
原文地址:https://www.cnblogs.com/kumata/p/9123808.html