数据结构之排序
Posted 小小菜_v
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构之排序相关的知识,希望对你有一定的参考价值。
冒泡排序(时间复杂度:O(n^2))
1、比较两个相邻的元素,如果前一个大于后一个则交换位置;
2、对后面的元素都做第一步的操作,从首部开始到尾部结束,最终最大的元素将会排在最后一位;
3、循环重复上面一,二步操作,列表长度减一(不包含最后的一位元素,因为已是最大,无需排序)
4、直到没有数字比较,循环结束
方式一
def bubble_sort(lis):
"""
冒泡排序
:param lis:
:return:
"""
for i in range(len(lis)-1):
for j in range(len(lis)-i-1):
if lis[j] > lis[j+1]:
lis[j], lis[j+1] = lis[j+1], lis[j]
print(lis)
lis = [3, 1, 2, 4, 9, 4, 10, 7]
bubble_sort(lis)
输出
C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/bubble_sort.py
[1, 2, 3, 4, 4, 9, 7, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
从输出结果可以看出,第二趟就排序好了,但是后面还是循环了5次,我们可以进行优化一下
def bubble_sort(lis):
"""
冒泡排序
:param lis:
:return:
"""
for i in range(len(lis)-1):
flag = False
for j in range(len(lis)-i-1):
if lis[j] > lis[j+1]:
lis[j], lis[j+1] = lis[j+1], lis[j]
flag = True
if not flag:
break
print(lis)
lis = [3, 1, 2, 4, 9, 4, 10, 7]
bubble_sort_v2(lis)
输出
C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/bubble_sort.py
[1, 2, 3, 4, 4, 9, 7, 10]
[1, 2, 3, 4, 4, 7, 9, 10]
当加一个标志,判断没有进行交换一次,那么就可以结束循环
选择排序(时间复杂度:O(n^2))
1、首先选择第一个元素的下标记录下来min_loc ;
2、从第二个元素开始,进行循环遍历,将取出来的元素和第一步选择的元素比较,若小于它,交换他们的下标,继续循环,直到找到最小的那个元素
循环结束,判断min_loc 是否和第一步记录下来的值相等,不等,则交换对应的元素值
def select_sort(lis):
"""
选择排序
:param lis:
:return:
"""
for i in range(len(lis)-1): # 第一次循环元素下标
min_loc = i
for j in range(i+1, len(lis)): # 第二个元素下标
if lis[min_loc] > lis[j]: # 找到比min_loc所在位置小的元素
min_loc = j # min_loc重新赋值j
if min_loc != i: #比较min_loc ,不同则交换元素值
lis[min_loc], lis[i] = lis[i], lis[min_loc]
print(lis)
lis = [3, 1, 2, 4, 9, 4, 2, 7]
print(lis)
select_sort(lis)
输出
C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/select_sort.py
[3, 1, 2, 4, 9, 4, 2, 7]
[1, 3, 2, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 9, 4, 2, 7]
[1, 2, 2, 4, 9, 4, 3, 7]
[1, 2, 2, 3, 9, 4, 4, 7]
[1, 2, 2, 3, 4, 9, 4, 7]
[1, 2, 2, 3, 4, 4, 9, 7]
[1, 2, 2, 3, 4, 4, 7, 9]
插入排序(时间复杂度:O(n^2))
插入排序相当于摸扑克牌,摸到下张牌与手中的牌进行对比,然后插入到合适的位置
1、手中已存在第一张牌,从第二张开始遍历
2、第二张和第一张比较,小于的话,需要交换位置插入到第一张前面
3、继续循环
def insert_sort(lis):
"""
插入排序
:param lis:
:return:
"""
for i in range(1, len(lis)): #i从第二个元素开始
temp = lis[i] # 记录元素值
j = i - 1 # 手中最右边的牌的下标
while j >= 0 and lis[j] > temp:
lis[j+1] = lis[j]
j = j - 1
lis[j + 1] = temp
print(lis)
lis = [3, 1, 2, 4, 9, 4, 2, 7]
insert_sort(lis)
输出
C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/insert_sort.py
[3, 1, 2, 4, 9, 4, 2, 7]
[1, 3, 2, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 9, 4, 2, 7]
[1, 2, 3, 4, 4, 9, 2, 7]
[1, 2, 2, 3, 4, 4, 9, 7]
[1, 2, 2, 3, 4, 4, 7, 9]
快速排序(时间复杂度(一般):O(nlogN))
1、取第一个元素temp,使temp归位到它应该在的位置,归位后,列表分为两部分,左边比temp小,右边比temp大;
递归完成排序
def partition(lis, left, right):
temp = lis[left] # 第一个元素
while left < right:
while left < right and lis[right] >= temp:
right -= 1
lis[left] = lis[right]
while left < right and lis[left] <= temp:
left += 1
lis[right] = lis[left]
lis[left] = temp
print(lis)
return left
def quick_sorrt(lis, left, right):
"""
快排
:param lis:
:param left:
:param right:
:return:
"""
if left < right: # 两个指针,left为首部,right为尾部
mid = partition(lis, left, right) # 获取元素temp归位后的下标
quick_sorrt(lis, left, mid-1) # 递归列表左部分
quick_sorrt(lis, mid+1, right) # 递归列表右部分
lis = [3, 1, 2, 4, 9, 4, 2, 7]
print(lis)
quick_sorrt(lis, 0, len(lis)-1)
输出
C:\\Users\\MI\\AppData\\Local\\Programs\\Python\\Python310\\python.exe D:/python/quick_sort.py
[3, 1, 2, 4, 9, 4, 2, 7]
[2, 1, 2, 3, 9, 4, 4, 7]
[1, 2, 2, 3, 9, 4, 4, 7]
[1, 2, 2, 3, 7, 4, 4, 9]
[1, 2, 2, 3, 4, 4, 7, 9]
[1, 2, 2, 3, 4, 4, 7, 9]
最坏情况:
1、递归的最大深度默认是1000,可以通过sys.setrecursionlimit(1005)修改;
2、当列表是逆序的情况下,每次递归就没有折半了(第一个temp可以随机选择一个)
以上是关于数据结构之排序的主要内容,如果未能解决你的问题,请参考以下文章