一、排序算法
交换类排序:冒泡排序和快速排序
a.冒泡排序:从头开始,依次比较相邻两个元素的大小,如果前一个比后一个大,就交换位置,依次循环n-1次,每次将该次循环中最大的元素移至末尾;
常规版:
def bubble_sort(data):
for i in range(len(data)-1): # i用于控制循环次数
for j in range(len(data)-i-1): # j用于控制每次循环的比较次数
if data[j] > data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
return data
优化版:
假如此时有一个列表[6,1,2,3,4,5],在进行第一次循环后,列表就是有序的了,
但是此时程序还是会继续执行,但是此时做的都是无用功,那么此时要如何避免呢?
def bubble_sort_better(data):
for i in range(len(data)-1):
found = 0
for j in range(len(data)-i-1):
if data[j] > data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
found += 1
if found == 0: # 此时如果found=0,表示此次循环中,该列表中的元素为有序的,所以此时结束本次循环进入下一个循环;
break
return data
b.快速排序:通过选择一个标准值,将数组一分为二,比该值小的元素划分到左边,比该值大的元素划分到右边,然后对左右两边的数组递归执行该操作,直至数组排好序;
def quick_sort(data, first, last):
if first == last:
return
pivot = data[first]
low = first
high = last
while low < high:
while low < high and data[high] > pivot:
high -= 1
data[low] = data[high]
while low < high and data[low] < pivot:
low += 1
data[high] = data[low]
data[low] = pivot
quick_sort(data, first, low-1)
quick_sort(data, low+1, last)
return data
快速排序的时间复杂度分析:
- 最优情况下:每次划分都比较均匀时
- 最差情况下:待排序序列为正序或者逆序,每次划分只得到一个比上一次划分少一个记录的子序列,另一个为空,此时画出递归树,它就是一棵斜树,此时需要执行n-1次递归调用,且第i次划分需要经过n-i次关键字的比较才能找到第i个记录,其最终复杂度为
- 平均情况下:其复杂度为
- 由于关键字的比较和交换是跳跃进行的,所以快排是一种不稳定的排序方法;
插入排序类:插入排序和希尔排序
c.插入排序:将待排序数组分为已排序和未排序两部分,每次从未排序部分中取出第一个元素,将其从后往前与已排序部分进行比较,然后插入到适当的位置中,达到将数组进行排序的目的;
def insert_sort(data):
for i in range(1, len(data)): # 从第二个元素开始进行比较
for j in range(i,0,-1): # 从已排序部分从后往前依次进行
if data[j] < data[j-1]:
data[j], data[j-1] = data[j-1], data[j]
return data
d.希尔排序:先将整个待排序的记录序列分割成为若干子序列分别进行直接插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行依次直接插入排序。
##插入排序
def insert_sort(data):
n = len(data)
for j in range(1, n):
i = j
while i >0:
if data[i] < data[i-1]:
data[i], data[i-1] = data[i], data[i-1]
i -= 1
else:
break
return data
## 希尔排序
def shell_sort(data):
gap = len(data) // 2
while gap >= 1:
for j in range(gap, len(data)):
i = j
while (i - gap) >= 0:
if data[i] < data[i-gap]:
data[i], data[i-gap] = data[i-gap], data[i]
i -= gap
else:
break
gap //= 2
return data
- 稳定性分析:希尔排序的关键在于将相隔某个“gap”的记录组成一个子序列,实现跳跃式的移动,实现排序的效率提高。
- 由于希尔排序时记录属于跳跃式的移动,所以希尔排序并是一种不稳定的排序算法;
e.选择排序:首先假设数组中的第一个元素为最小值,然后依次将其与之后的元素进行比较,如果之后有元素值比它小,则将该元素设为最小值;
def select_sort(data):
for i in range(len(data)-1):
min_index = i
for j in range(i+1, len(data)):
if data[j] < data[min_index]:
min_index = j
data[i], data[min_index] = data[min_index], data[i]
return data
f.堆排序:
各种算法的指标
未完待续