一、冒泡排序(Bubble sort)
基本思想:两个数比较大小,如果顺序不对,就把两个数交换位置
过程(从小到大排序):
- 一次比较相邻的两个数组元素,如果前一个数大于第二个数,则交换两个数字的位置
- 从前向后两两比较,一直比较到最后的两个数,最小的数被交换到最前
- 重复上述过程,直至全部排序完成
时间复杂度:
- 最好时间复杂度:O(n)--初始状态的排序就是最终结果
- 最坏时间复杂度:O(n*n)--初始状态的排序与最终结果恰好相反
- 平均时间复杂度:O(n*n)
#!/usr/bin/python3
# -*- coding:utf-8 -*-
def bubble(nums):
for i in range(len(nums)-1): #一共遍历len(nums)-1次
for j in range(len(nums)-i-1):
if nums[j] > nums[j+1]:
# temp = nums[j] 引入临时变量
# nums[j] = nums[j+1]
# nums[j+1] = temp
nums[j],nums[j+1] = nums[j+1],nums[j]
return nums
nums = [42, 13, 35, 20, 12, 19]
print(bubble(nums))
以上是最简单的冒泡排序方法,内层循环在某次比较没有进行交换时,说明此时已经是有序排列,无需下次比较了,但是冒泡排序仍会比较到len(nums)-1项,所以可以针对这一问题进行优化:
#!/usr/bin/python3
# -*- coding:utf-8 -*-
def opt_bubble(nums):
for i in range(len(nums)-1):
exchange = False #判断是否进行过交换的标记
for j in range(len(nums)-i-1):
if nums[j] > nums[j+1]:
nums[j],nums[j+1] = nums[j+1],nums[j]
exchange = True
if exchange == False:
break
return nums
nums = [42, 13, 35, 20, 12, 19]
print(opt_bubble(nums))
二、选择排序
基本思想:遍历数组,找到最小(最大)的数值与第一个数值交换,然后找第二小的数值放在第二位,直至最后一位
时间复杂度:O(n*n)
#!/usr/bin/python3
# -*- coding:utf-8 -*-
def selection(nums):
for i in range(len(nums)-1): #一共遍历len(nums)-1次
for j in range(i+1, len(nums)): #依次与后项比较
if nums[i] > nums[j]:
nums[i], nums[j] = nums[j], nums[i]
return nums
nums = [20, 15, 18, 1, 10, 11]
print(selection(nums))
三、插入排序(Insertion sort)
基本思想:假设第一个数字已经排序好,第二个数字与第一个数字进行比较后插入到适当的位置,依次类推,直至插入完成
平均时间复杂度:O(n*n)
#!/usr/bin/python3
# -*- coding:utf-8 -*-
def insertion(nums):
for i in range(1, len(nums)-1): #第一个数有序
for j in range(i+1, 0, -1):
if nums[j] < nums[j-1]: #与已排序的一一比较
nums[j], nums[j-1] = nums[j-1], nums[j]
print(nums)
else:
break
return nums
nums = [10,13,6,15,30,9]
print(insertion(nums))
四、希尔排序(Shell's sort)
希尔排序是插入排序的一种,又称“缩小增量排序”
基本思想:将无序的数组分为若干个相隔特定增量的子序列,并对各个子序列插入排序,然后取一个更小的增量插入排序,直至增量为1,得到一个基本有序的数列,在进行插入排序
平均时间复杂度:优于直接插入排序
#!/usr/bin/python3
# -*- coding:utf-8 -*-
def shell(nums):
k = int(0)
increment = int(len(nums) / 2)
while increment > 1: #一直循环至增量为1
increment = int(increment / 2)
for k in range(0, increment+1):
for i in range(k+increment, len(nums), increment): #从每个分组的第一个数开始,到分组的最后一个,步长为增量
for j in range(i, k, -increment):
if nums[j] < nums[j-increment]: #前一个数比后一个数大,则交换位置
nums[j], nums[j-increment] = nums[j-increment], nums[j]
else:
break
return nums
nums = [ 12, 10, 5, 8, 9, 6, 7, 11 ]
print(shell(nums))
五、快速排序(Quick sort)
基本思想:取第一个数为key值,后面的数依次和key值作比较,比key值小的放在左边,大的放在右边;对左右两边的小数列重复上述步骤
时间复杂度:O(N*logN)
#!/usr/bin/python3
# -*- coding:utf-8 -*-
nums = [14, 13, 15, 12, 16]
def quick(nums):
quick_sort(nums, 0, len(nums)-1)
def quick_sort(nums, l, r):
if l-r > 0: #判断数字是否多于一个,是的话排序,不是则停止
return
i = l
j = r
key = nums[i] #将数组的第一个数字设为关键字
while i < j:
while i < j and nums[j] >= key:
j -= 1
if i < j:
nums[i] = nums[j]
i += 1
while i < j and nums[i] <= key:
i += 1
if i < j:
nums[j] = nums[i]
j -= 1
nums[i] = key
quick_sort(nums, l, i-1) #递归
quick_sort(nums, i+1, r)
quick(nums)
print(nums)
六、归并排序(Merge sort)
基本思想:是建立在归并操作上的一种有效的排序算法,将两个有序数列合并,进行比较,如果数列为空,则直接将另一个数列数据依次取出即可
不小心发布了。。。还没写完