效率和稳定性
冒泡排序
冒泡排序就是前一个和后一个比较,把最大的数往后沉
def bubble1_sort(li):
"""冒泡排序"""
n = len(li)
count = 0
# 控制循环次数
for i in range(n-1):
for j in range(n-1-i):
# 若当前元素比后一个大,就交换位置
# 一直和后一个元素比较,把最大的往后沉
if li[j] > li[j+1]:
li[j+1],li[j] = li[j],li[j+1]
count += 1
# 如果没有进行交换,则说名是有序的,直接结束循环
if count == 0:
break
if __name__ == '__main__':
list1 = [17,14,12,5,11,24,2,6,15,19,8,3,9]
bubble1_sort(list1)
print(list1)
选择排序
def choose_sort(li):
"""选择排序"""
n = len(li)
# 控制循环次数
for j in range(0,n-1):
min_index = j
# j之前是有序的,之后是无序的
for i in range(j+1,n):
# 如果是有比j小的元素就把这个元素的索引赋值给j
if li[i] < li[j]:
j = i
# 如果进行了比较并改变了j就进行交换元素,若没有变化,说明是对应的位置,不进行交换减小时间复杂度
# 把索引是j的元素换到min_index这个位置
if min_index != j:
li[j],li[min_index] = li[min_index],li[j]
if __name__ == '__main__':
list1 = [17,14,12,5,11,24,2,6,15,19,8,3,9]
choose_sort(list1)
print(list1)
插入排序
def insert_sort(li):
"""插入排序"""
n = len(li)
# 取出元素j
for j in range(1,n):
# j前面的元素是有序的
# 当前元素和前一个比较
for i in range(j,0,-1):
if li[i] < li[i-1]:
# 比前一个小进行交换
li[i],li[i-1] = li[i-1],li[i]
else:
# 如果条件不满足说明这个元素比前面的元素都大,放在当前位置结束当前循环
break
if __name__ == '__main__':
list1 = [17,14,12,5,11,24,2,6,15,19,8,3,9]
insert_sort(list1)
print(list1)
希尔排序
希尔排序就是分组后进行插入排序
def shell_sort1(li):
"""希尔排序第一次练习"""
n = len(li)
# 分组
gap = n // 2
# 只要步长大于等于1,就继续进行插入排序,继续分组
while gap >= 1:
# 每次从第二组开始,也就是第一个步长开始,和前一个步长的元素比较
for j in range(gap,n):
while (j-gap) >= 0:
# 当前元素小的话就往前交换,直到合适位置
if li[j] < li[j-gap]:
li[j],li[j-gap] = li[j-gap],li[j]
else:
# 如果条件不满足,则说明当前元素大,不用往前交换,结束当前循环
break
# 控制循环,不断往前交换
j -= gap
# 不断分组,进行插入
gap //= 2
if __name__ == '__main__':
list1 = [17, 14, 12, 5, 11, 24, 2, 6, 15, 19, 8, 3, 9]
shell_sort1(list1)
print(list1)
快速排序
快速排序的特点就是取出一个元素,然后用两个游标,从右左依次取出元素和这个元素比较,小的往左,大的往右交换,这两个游标重合时,就找到了这个元素的位置。然后序列分两部分,分别重复刚才的过程(递归)。
def quick_sort(li,start,end):
"""快速排序"""
# 当序列只有一个元素时,就返回
if start >= end:
return
# 创建2个游标
left = start
right = end
# 取出第一个元素
mid = li[start]
while left < right:
# 拿右边元素逐一和mid进行比较
while left < right and li[right] >= mid:
right -= 1
# 退出循环时,说明比mid小,把元素放到左游标的位置
li[left] = li[right]
# 然后左游标进行比较移动
while left < right and li[left] < mid:
left += 1
# 左边大于mid的往右游标位置放
li[right] = li[left]
# 当游标重合时,则说明移动结束,把mid放到游标重合处,左边是比它小的,右边是比它大的
li[left] = mid
# 递归调用
quick_sort(li,start,left-1)
quick_sort(li,left+1,end)
if __name__ == '__main__':
list1 = [17, 14, 12, 5, 11, 24, 2, 6, 15, 19, 8, 3, 9]
quick_sort(list1,0,len(list1)-1)
print(list1)
归并排序
归并排序就是先分组,递归分组,把序列分成一个一个元素的序列,然后再合并这些有序的序列。
def merge_sort(li):
"""归并排序"""
n = len(li)
if n <= 1:
return li
# 拆分
mid = n // 2
# 递归拆分
left_li = merge_sort(li[:mid])
right_li = merge_sort(li[mid:])
# 合并,每个序列是有序的
left,right = 0,0
merge = list()
left_n = len(left_li)
right_n = len(left_li)
while left < left_n and right < right_n:
# 两个有序序列中的第一个元素谁小谁添加到列表中
if left_li[left] < right_li[right]:
merge.append(left_li[left])
left += 1
else:
merge.append(right_li[right])
right += 1
# 退出循环后,把剩余的元素追加到列表中
merge += left_li[left:]
merge += right_li[gight:]
# 返回排好序的新列表
return merge
if __name__ == '__main__':
list1 = [17, 14, 12, 5, 11, 24, 2, 6, 15, 19, 8, 3, 9]
print(merge_sort(list1))