学习量化也有一段时间了,借csdn博客记录下学习过程的点点滴滴。
准备总结的内容:
(1)CFA二级知识点;(2)期权期货相关(魏振祥《商品期权》总结);(3)统计学(可汗学院统计学课程总结);(4)数据结构与leetcode的一些实践(python实现);(5)一些简单设计模式的python实现;(6)基于tushare的一些策略实现(均线策略与择股策略等);(7)时间序列分析;
接下来几篇为python3实现的排序算法。
(一)冒泡算法。
首先最初级的冒泡算法,每次iteration会将i位置的数据调整至最小值,但是其他位置数据并没有变得更加有序,故效率较低。
def bubble_sort(src):
if len(src) == 0:
return src
for i in range(len(src)):
for j in range(i+1, len(src)):
if src[j] < src[i]:
tem = src[j]
src[j] = src[i]
src[i] = tem
return src
src = [10, 12, 8, 9, 20, 18, 40, 15]
print(bubble_sort(src))
接下来改进版的冒泡算法,每次交换会把数据变得更加有序。
这么写的话,每次循环是将最大的值放到最后,不是严格意义的冒泡,如果是每次循环将最小的元素排到最前,第二层循环应该从后往前,for j in range(len(src)-1, i, -1),循环内判断条件为if src[j] < src[j-1],将两个元素互换。
def bubble_sort(src):
if len(src) == 0:
return src
for i in range(len(src)):
for j in range(0, len(src)-i-1):
if src[j] > src[j+1]:
tem = src[j]
src[j] = src[j+1]
src[j+1] = tem
return src
src = [10, 12, 8, 9, 20, 18, 40, 15]
print(bubble_sort(src))
如果有一次循环已经没有交换元素,那说明已经排序完成,没必要继续循环了,加入flag判断代码如下。
def bubble_sort(src):
if len(src) == 0:
return src
flag = True
for i in range(len(src)):
if not flag:
break
flag = False
for j in range(len(src)-1, i, -1):
if src[j-1] > src[j]:
tem = src[j]
src[j] = src[j-1]
src[j-1] = tem
flag = True
return src
冒泡算法最好情况是比较n-1次,时间复杂度是O(n),最坏情况是1+2+...+n-1=n(n-1)/2,时间复杂度O(n^2)。
(二)选择排序算法。
i每次循环将i+1及之后里面最小的与i进行交换,i最后循环到len(src)-2就行。
def selected_sort(src):
if len(src) == 0:
return src
for i in range(len(src)-1):
min = i
for j in range(i+1, len(src)):
if src[j] < src[min]:
min = j
if i != min:
tem = src[min]
src[min] = src[i]
src[i] = tem
return src
src = [10, 12, 8, 9, 20, 18, 40, 15]
print(selected_sort(src))
时间复杂度也为O(n^2)。
(三)直接插入排序。每次i循环将i位置元素插入到0至i-1序列中。
def insert_sort(src):
if len(src) == 0:
return src
for i in range(1, len(src)):
j = i-1
tem = src[i]
while j >= 0:
if tem < src[j]:
src[j+1] = src[j]
else:
src[j+1] = tem
break
j -= 1
if j < 0:#如果j循环结束而不是break结束的情况,说明原来的src[0]都比tem小
src[0] = tem
return src
src = [10, 12, 8, 9, 20, 18, 40, 15]
print(insert_sort(src))
时间复杂度也为O(n^2)。
这篇文章先写这么多,接下来继续。
(四)希尔排序,设置一个incremental对原序列提取出子序列,对子序列直接插入排序,然后逐渐减小步长,直至步长为1。
def shell_sort(src):
if len(src) == 0:
return src
incremental = len(src)
while incremental >= 1:
for i in range(0, len(src)):#i为每组的第一个元素
for j in range(i, len(src), incremental):#j为每组间隔incremental的元素
if j == i:#第一个元素不用排序
continue
#插入排序
tem = src[j]
k = j - incremental
while k >= i:
if src[k] > tem:
src[k+incremental] = src[k]
k -= incremental
else:
src[k+incremental] = tem
break
if k < i:
src[i] = tem
incremental = int(incremental/2)
return src
src = [10, 12, 8, 9, 20, 18, 40, 15]
print(shell_sort(src))
(五)归并排序,递归至同类小问题,再归并排序。
def merge(left, right):
res = []
i, j = 0, 0
while i < len(left) and j < len(right):
if left[i] < right[j]:
res.append(left[i])
i += 1
else:
res.append(right[j])
j += 1
while i < len(left):
res.append(left[i])
i += 1
while j < len(right):
res.append(right[j])
j += 1
return res
def merge_sort(src):
if len(src) <= 1:
return src
middle = int(len(src)/2)
left = merge_sort(src[:middle])
right = merge_sort(src[middle:])
return merge(left, right)
src = [10, 12, 8, 9, 20, 18, 40, 15]
print(merge_sort(src))
归并排序时间复杂度O(nlogn),为稳定的排序算法。
(六)快速排序,设置partition,每次将元素依照key分割开,再递归排序两边的元素。
def quick_sort(src, left, right):
if left >= right:
return src
low = left
high = right
key = src[left]
while low < high:
while low < high and src[high] >= key:
high -= 1
src[low] = src[high]
while low < high and src[low] <= key:
low += 1
src[high] = src[low]
src[low] = key
quick_sort(src, left, low-1)
quick_sort(src, low+1, right)
return src
src = [10, 12, 8, 9, 20, 18, 40, 15]
print(quick_sort(src, 0, len(src)-1))
时间复杂度为O(nlogn),非稳定的排序算法。
(七)堆排序,时间复杂度O(nlogn)
def heap_sort(src):
length = len(src)
if len(src) <= 1:
return src
def adjust_heap(src, i, end):
tem = src[i]
k = 2*i+1#左孩子index
while k <= end:
if k+1 <= end and src[k] < src[k+1]:
k += 1
if tem < src[k]:
src[i] = src[k]
i = k
k = 2*k + 1
else:
break
src[i] = tem
for i in range(int((length-1)/2), -1, -1):
adjust_heap(src, i, length-1)
for j in range(length-1, 0, -1):
src[0], src[j] = src[j], src[0]
adjust_heap(src, 0, j-1)
return src
print(heap_sort([5,4,3,2,1]))