开始的话:
从基础做起,不断学习,坚持不懈,加油。
一位爱生活爱技术来自火星的程序汪
1. 归并排序
用到了分治思想:将一个大问题分解成小问题,小问题解决了,大问题也就解决了。用到了分治思想:将一个大问题分解成小问题,小问题解决了,大问题也就解决了。
这个和递归recursion很像,分治一般都是用递归来实现。
分治是一种解决问题的处理思想
递归是一种编程技巧
写递归的技巧:
- 递推公式;
- 终止条件
思想:
把一个数组从中间拆分开,一直拆分到length为1,然后 比较 合并,得到最终的排序好的数组。
有一个拆分(
p
a
r
t
part
part) 合并(
m
e
r
g
e
merge
merge)的过程
给定一个从p到r的数组
递推公式:
merge_sort(p…r) = merge(merge_sort_part(p…q), merge_sort_part(q+1…r))
终止条件:
p == r 不用再继续分解
细节
在merge中,分别遍历两个数组进行比较,每次把小的值放到一个临时数组中,比较完把非空的数组中的值拷贝到临时数组。并最终把临时数组复制到原始数组中。
s h o w show show m y my my c o d e code code
# -*- coding:utf-8 -*-
"""
@contact: adonis_wu@outlook.com
@file: myMergeSort.py
@time: 2018/11/29 09:41
"""
__author__ = '? adowu ?'
def merge_sort(arr: list, n: int):
"""
:param arr: array
:param n: array size
:return: sorted array
"""
merge_sort_part(arr, 0, n - 1)
return arr
def merge_sort_part(arr: list, start: int, end: int):
"""
:param arr: array
:param start: current start
:param end: current end
:return: sorted array
"""
if start == end:
return
mid_left = int((start + end) / 2)
mid_right = int((start + end) / 2) + 1
merge_sort_part(arr, start, mid_left)
merge_sort_part(arr, mid_right, end)
merge(arr, start, mid_left, mid_right, end)
def merge(original_array: list, left_index: int, mid_left_index: int, mid_right_index: int, right_index: int):
"""
:param original_array: original array
:param left_index: current left index
:param mid_left_index: current mid left index
:param mid_right_index: current mid right index
:param right_index: current right index
:return:
"""
tmp_array = [0] * (right_index - left_index + 1)
tmp_index = 0
p, q, j, k = left_index, mid_left_index, mid_right_index, right_index
while (p <= q) and (j <= k):
if original_array[p] <= original_array[j]:
tmp_array[tmp_index] = original_array[p]
p += 1
else:
tmp_array[tmp_index] = original_array[j]
j += 1
tmp_index += 1
# rest elements copy to original array
start, end = p, q
if j <= k:
start, end = j, k
tmp_array[tmp_index:] = original_array[start:end + 1]
original_array[left_index:right_index + 1] = tmp_array
return original_array
if __name__ == '__main__':
a1 = [3, 5, 6, 7, 8]
a2 = [2, 2, 2, 2]
a3 = [4, 3, 2, 1]
a4 = [5, -1, 9, 3, 7, 8, 3, -2, 9]
merge_sort(a1, len(a1))
print(a1)
merge_sort(a2, len(a2))
print(a2)
merge_sort(a3, len(a3))
print(a3)
merge_sort(a4, len(a4))
print(a4)
2. 快速排序
快速排序,简称为“快排”,运用的也是分治思想。
思想:
给定一个从p到r的数组,首先会随机选择一个值作为分区点:pivot,
然后遍历 余下 的数据, 小的放左边,大的放右边,一直这样分下去。
递推公式:
quick_sort(p…r) = quick_sort_part(p,q-1) + quick_sort_part(q+1, r)
终止条件:
p >= r
细节:
归并中有一个merge,快排中有一个partition在partition中为了保证是原地排序:利用两个下标,将小的值放在pivot的左边,大值放在右边。
s h o w show show m y my my c o d e code code
# -*- coding:utf-8 -*-
"""
@contact: adonis_wu@outlook.com
@file: myQuickSort.py
@time: 2018/11/29 14:26
"""
__author__ = '? adowu ?'
import random
def quick_sort(arr: list, n: int):
"""
:param arr: array
:param n: len array
:return: sorted array
"""
quick_sort_part(arr, 0, n - 1)
def quick_sort_part(arr: list, start: int, end: int):
"""
:param arr: original array
:param start: current start index
:param end: current end index
:return:
"""
if start >= end:
return
pivot_index = partition(arr, start, end)
quick_sort_part(arr, start, pivot_index - 1)
quick_sort_part(arr, pivot_index + 1, end)
def partition(arr: list, start: int, end: int):
"""
:param arr: original array
:param start: current start index
:param end: current end index
:return: partition index
"""
k = random.randint(start, end)
arr[end], arr[k] = arr[k], arr[end]
pivot = arr[end]
first_big_index = start
for i in range(start, end):
if arr[i] < pivot:
arr[first_big_index], arr[i] = arr[i], arr[first_big_index]
first_big_index += 1
arr[first_big_index], arr[end] = arr[end], arr[first_big_index]
return first_big_index
if __name__ == '__main__':
a1 = [3, 5, 6, 7, 8]
a2 = [2, 2, 2, 2]
a3 = [4, 3, 2, 1]
a4 = [5, -1, 9, 3, 7, 8, 3, -2, 9]
quick_sort(a1, len(a1))
print(a1)
quick_sort(a2, len(a2))
print(a2)
quick_sort(a3, len(a3))
print(a3)
quick_sort(a4, len(a4))
print(a4)
谢谢
更多代码请移步我的个人 g i t h u b github github,会不定期更新。
本章代码见 c o d e code code
欢迎关注