冒泡排序(BubbleSort)
冒泡排序是基本的一种排序算法,实现思想是:从数组头到尾相邻的两个数两两比较,(从小到大排序)然后把值比较大的那个数一直放在比较两数中的后一个,这样大的数会一直的往数组后面走,直到该比较趟数的最后一个..整个过程那个大的数就像冒泡一样一直往后走..可能这就是名字的由来吧
def bubbleSort(l):
leght = len(l)
for i in range(leght):
flag = False
for j in range(0,leght-i-1):
if l[j] > l[j+1]:
l[j],l[j+1] = l[j+1],l[j]
flag = True
if not flag : break
return l
flag 的作用是当遍历某一趟的时候,没有任何值进行交换的时候,说明这个数组从头到尾都是有序的了,这个时候就可能退出来了,不需要继续后面的排序了
冒泡排序 : 空间复杂度是o(1),属于原地排序算法;
属于稳定的排序算法(稳定是指当数组内出现两个相同的数时,排序后他们的顺序与排序前的一致);
最好时间复杂度为o(n),最坏时间复杂度为o(n^2),平均时间复杂度为o(n^2)
插入排序(InsertionSort)
插入排序的思想 : 操作数组分为有序区间和无序区间,不断的从无序区间里面拿一个数出来,再插入到有序区间内
方法一 : 每次交换的时候都是使用的两两交换
def insertionSort(l):
leght = len(l)
if leght <= 1 : return l
for i in range(leght-1):
j = i + 1
while(j>0):
if (l[j] < l[j-1]):
l[j],l[j-1] = l[j-1],l[j]
else:
break
j -= 1
return l
方法二: 使用了一个临时变量,但是每次交换只有一次赋值运算,根据系数判断这个运行起来的时间复杂度会比上面快
def insertionSort(l):
leght = len(l)
if leght <= 1 : return l
for i in range(1,leght):
value = l[i]
j = i - 1
while (j>=0):
if l[j] > value :
l[j+1] = l[j]
else:
break
j -= 1
l[j+1] = value
return l
插入排序 : 空间复杂度是o(1),属于原地排序算法;
属于稳定的排序算法;
最好时间复杂度为o(n),最坏时间复杂度为o(n^2),平均时间复杂度为o(n^2)
选择排序
思路: 分为已排序区间和未排序区间 ,从未排序区间中选择出最小的值放入已排序区间中
def selectionSort(l):
for i in range(len(l)):
min_index = i
for j in range(i,len(l)):
if l[j] < l[min_index]:
min_index = j
if min_index != i :
l[i] ,l[min_index] = l[min_index],l[i]
return l
选择排序 : 空间复杂度是o(1),属于原地排序算法;
属于不稳定的排序算法; 比如 [3,10,3,45,2,6] 这样的话3的位置就变了
最好时间复杂度为o(n^2),最坏时间复杂度为o(n^2),平均时间复杂度为o(n^2)
对于这三个算法的测试,生成了很多次(多次测试避免误差)的同一些数组排序,最后发现选择排序跑出来的速度居然比插入快
"""
冒泡执行排序1000个数组 所用时间为 10.046544313430786
插入执行排序1000个数组 所用时间为 4.30054235458374
选择执行排序1000个数组 所用时间为 3.758864164352417
"""
这个我是觉得不太对的,因为我觉得 一个 最坏时间复杂度,最好时间复杂度,平均时间复杂度都是 o(n^2)的算法,比一个 最坏时间复杂度为O(n^2),最好时间复杂度为o(n),平均时间复杂度都是 o(n^2)的算法,同时执行相同组组数进行排序,那个有最好时间复杂度为o(n)应该会快点的!
然后详细的根据上面代码进行分析后,发现我写的那个选择排序的 时间复杂度为 8n^2 ,而插入排序(算的是第二种,第一种的速度比第二种慢太多了)的时间复杂度为 9n^2 ; 虽然最好时间复杂度是插入排序好点,但是这个系数却是选择排序更小点!由此可看出在相同的平均复杂度的时候,系数的影响会比最好时间复杂度会大点...