- 归并排序(分治策略)
- 快速排序
归并排序(分治策略)
归并排序是递归算法,思路是将数据表持续分裂为两半,对两半分别进行归并排序。
- 递归的基本结束条件:数据表仅有一项数据,自然是排好序的;
- 缩小规模:将数据表分裂为相等的两半,规模减小为原来的二分之一;
- 调用自身:将两半分别调用自身排序,然后将排好序的两半进行归并,得到排好序的数据表;
def mergeSort(alist): #基本结束条件 if len(alist) > 1: mid = len(alist) // 2 left = alist[:mid] right = alist[mid:] #递归调用 mergeSort(left) mergeSort(right) #拉链式交错把左右半部分从小到大归并到结果列表中 i = j = k = 0 while i < len(left) and j < len(right): if left[i] < right[j]: alist[k] = left[i] i += 1 else: alist[k] = right[j] j += 1 k += 1 #归并左半部分剩余项 while i < len(left): alist[k] = left[i] i += 1 k += 1 #归并右半部剩余项 while j < len(right): alist[k] = right[j] j += 1 k += 1 return alist test_list = [54,2,1,77,100,15,12,18] print(mergeSort(test_list))
另一种归并排序代码;(更符合python风格)
def merge_Sort(alist): #递归结束条件 if len(alist) <= 1: return alist #递归调用 mid = len(alist) // 2 left = merge_Sort(alist[:mid]) right = merge_Sort(alist[mid:]) merged = [] while left and right: if left[0] <= right[0]: merged.append(left.pop(0)) else: merged.append(right.pop(0)) merged.extend(right if right else left) return merged test_list = [54, 2, 1, 77, 100, 15, 12, 18] print(merge_Sort(test_list))
归并算法的两个过程:分裂和归并。
分裂的过程时间复杂度:O(logn);
归并的过程时间复杂度:O(n);
总的时间复杂度:O(nlogn)。
另外归并排序算法使用了额外的一倍的存储空间,当数据集较大时进行排序,需要考虑进去。
快速排序快速排序的思路是:依据一个“中值”数据项把数据表分为两半:小于中值的一半和大于中值的一半,然后每部分分别进行快速排序(递归)。
避免中位数的计算开销,所以随意找一个熟充当“中值”。
快速排序的递归三要素;
- 基本结束条件:数据表仅有1个数据项,自然是排好序的;
- 缩小规模:根据‘中值’,将数据表分为两半,最好情况是相等规模的两半;
- 调用自身:将两半分别调用自身进行排序(排序基本 *** 作在分裂过程中)。
算法步骤:
- 找到分裂数据表的目标(中值):数据表的第一项;
- 分裂数据表
设置左右标,左标向右移动,右标向左移动;
1、左标一直向右移动,碰到比中值大的就停止;
2、右标一直向左移动,碰到比中值小的就停止;
3、然后把左右标所指的数据项交换。 - 继续移动,直到左标移到右标的右侧,停止移动;这时右标所指的位置就是中值应处的位置;
- 将中值和这个位置交换,这样做半部分比中值小,右半部分比中值大。
def quick_Sort(alist): quick_Sort_Helper(alist, 0, len(alist)-1) return alist def quick_Sort_Helper(alist, left, right): #基本结束条件 if left < right: #分裂 split_point = partition(alist, left, right) #递归调用 quick_Sort_Helper(alist, left, split_point-1) quick_Sort_Helper(alist, split_point+1, right) def partition(alist, left, right): p = alist[left] left_mark = left + 1 right_mark = right done = False while not done: #向右移动左标 while left_mark <= right_mark and alist[left_mark] <= p: left_mark = left_mark + 1 #向左移动右标 while alist[right_mark] >= p and right_mark >= left_mark: right_mark = right_mark - 1 #两标相错就结束移动 if right_mark < left_mark: done = True else: #左右标的值交换 alist[left_mark], alist[right_mark] = alist[right_mark], alist[left_mark] #中值就位 alist[left], alist[right_mark] = alist[right_mark], alist[left] return right_mark test_list = [54, 2, 1, 77, 100, 15, 12, 18] print(quick_Sort(test_list))
快速排序过程分为两部分:分裂和移动。
算法复杂度:O(nlogn)。
不稳定点:中值取值问题。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)