- 分析排序算法
- 排序算法的执行效率
(1)、时间复杂度的最好,最坏,平均情况
(2)、时间复杂度的系数,常数,低阶
(3)、比较次数和交换次数
2、排序算法的内存消耗
我们可以通过空间复杂度来衡量
- 排序算法的稳定性
稳定性就是经过排序之后,相等的元素的先后顺序不改变
- 常用的排序算法及实现
这里只些一些常用的排序算法如:冒泡排序、插入排序、希尔排序、选择排序、归并排序、快速排序、计数排序、基数排序、桶排序。
- 冒泡排序
- 原理
比较相邻的元素。如果第一个比第二个大,就交换他们两个。
对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
针对所有的元素重复以上的步骤,除了最后已经选出的元素(有序)。
持续每次对越来越少的元素(无序元素)重复上面的步骤,直到没有任何一对数字需要比较,则序列最终有序。
-
- 代码实现:
data = [1,3,2,6,4,5]
len_list = len(data)
for i in range(len_list):
for j in range(len_list-i-1):
if data[j] > data[j+1]:
data[j], data[j+1] = data[j+1], data[j]
-
- 代码优化:
如果冒泡操作已经没有数据交换时,说明已经达到完全有序,不用再执行冒泡操作
data = [1,3,2,6,4,5]
len_list = len(data)
for i in range(len_list):
count = 0
for j in range(len_list-i-1):
if data[j] > data[j+1]:
count += 1
data[j+1],data[j] = data[j],data[j+1]
if count == 0:
break
-
- 冒泡排序分析:
空间复杂度:冒泡排序只涉及相邻数据交换,所以空间复杂度为O(1)
稳定性:冒泡排序,如果相邻数据大小相等我们不会对其进行交换,所以相同大小的数据在排序前后不会改变顺序,所有冒泡排序是稳定的排序算法
时间复杂度:最好的情况,数据已经是有序的进行一次冒泡操作即可。所以最好时间复杂度为O(n)
最坏的情况是数据为逆序,需要进行n次冒泡操作所以最坏时间复杂度为O(n^2)
- 插入排序
- 原理
将数组分为已排序区间和未排序区间,初始状态是将数组第一个原素放在已排序空间,然后再未排序空间取出数据按顺序插入已排序空间。
-
- 代码实现
#encoding:utf-8
def charu(lis):
for i in range(1,len(lis)):
j = i-1
value = lis[i]
while j >=0:
if value < lis[j]:
lis[j+1] = lis[j]
lis[j] = value
j = j - 1
-
- 分析
空间复杂度:插入排序属于原地排序算法,所以其空间复杂度为O(1)
是否稳定:在插入时如果遇到值相同的数据,我们可以选择按先后顺序排序。这样插入排序就属于稳定的排序算法
时间复杂度:
最好时间复杂度:每次插入时只对比一次,就能确定插入位置,时间复杂度为O(n),
最坏时间复杂度:每次插入都要插入到数组的第一个位置,时间复杂度为O(n)
平均时间复杂度:在数组中插入数据的平均时间复杂度为O(n),需要执行n次插入操作。所以插入排序的平均时间复杂度为O(n^2)
- 希尔排序
- 原理:
先将待排序元素序列分割成多个子序列,然后再分别进行插入排序,然后依次缩小子序列个数,再进行排序。
-
- 代码:
#encoding:utf-8
def xier(lis):
num = len(lis)//2
while num > 0:
for i in range(num,len(lis)):
j = i - num
value = lis[i]
while j >= 0:
if value < lis[j]:
lis[j+num],lis[j] = lis[j],value
j -= num
num //= 2
-
- 分析:
空间复杂度:O(1)
时间复杂度:最优时间复杂度为O(nlogn)
最坏时间复杂度为O(n^2)
是否稳定:不稳定