排序算法总结
冒泡排序
冒泡排序可能是大家在大学计算机课程中接触的第一个排序算法,虽然其复杂度相对较高,但其中着眼于一点的问题解决方式是值得我们学习和借鉴的,当然我们可以先排最后一个位置的数,也可以先排最初始位置的数,其在编程上没有本质的区别,下面展示最典型的两种排法:
#先排最后的位置
def bub_sort(seq: list) -> list:
for j in range(len(seq)-1,0,-1):
for i in range(j):
if seq[i] > seq[i+1]:
seq[i],seq[i+1] = seq[i+1], seq[i]
return seq
#先排初始的位置
def bub_sort(seq: list) -> list:
for i in range(len(seq)):
for j in range(len(seq)-1, i, -1):
if seq[j] < seq[j-1]:
seq[j], seq[j-1] = seq[j-1], seq[j]
return seq
其递归的写法也就是把最外面一层循环换成递归的形式
插入排序
这个排序方式也是比较简单的,当然对于插入,我们也有二分插入,遍历插入等不同的方式
循环版本
def ins_sort(seq: list) -> list:
for i in range(1,len(seq)):
j = i
while j > 0 and seq[j-1] > seq[j]:
seq[j-1], seq[j] = seq[j], seq[j-1]
j -= 1
return seq
递归版本
def ins_sort(seq: list, i: int) -> list:
if i == 0:
return
ins_sort(seq,i-1)
j = i
while j > 0 and seq[j-1] > seq[j]:
seq[j-1], seq[j] = seq[j], seq[j-1]
j -= 1
return seq
最大值查找
查找的方法,当然还有最大值查找,方法很简单,我们只需要查找最大值然后交换就可以了
#循环版
def ins_sort(seq: list) -> list:
for i in range(len(seq)-1,0,-1):
max_val = i
for j in range(i):
if seq[max_val] < seq[j]:
max_val = j
seq[i], seq[max_val] = seq[max_val], seq[i]
return seq
#递归版
def ins_sort(seq: list, num: int) -> list:
if num == 0:
return
max_val = num
for j in range(max_val):
if seq[max_val] < seq[j]:
max_val = j
seq[num], seq[max_val] = seq[max_val], seq[num]
ins_sort_1(seq, num-1)
return seq
二分插入
我们现在是对插入方式进行优化,但二分插入还有许多其他的用处,比如说,我们通过二分插入去找一个有序序列插入时的索引等
def div(seq: list, end_num: int, num) -> list:
sta_num = 0
while sta_num <= end_num:
mid = (sta_num + end_num) // 2
if seq[mid] <= num:
sta_num = mid + 1
else:
end_num = mid - 1
seq.insert(sta_num, num)
def ins_sort(seq: list) -> list:
for i in range(1,len(seq)):
seq.pop(i)
div(seq, i-1, i)
return seq
这样进行排序的时候,结果没有什么大问题,但其实我们还可以再优化一下,因为进行一次pop和insert列表的存储位置都会发生变化,并且,这种变化是不必要的,其实我们可以用链表的数据结构进行优化,但链表的缺点也很明显,就是无法方便的访问数据。