冒泡排序的优化

算法思想:对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。

原始冒泡

相邻元素比较,大数后沉小数前移

  1. def bubble_sort(items):
  2. """冒泡排序 - O(N**2) """
  3. for i in range(1, len(items)):
  4. for j in range(0, len(items) - i):
  5. if items[j] > items[j + 1]:
  6. items[j], items[j + 1] = items[j + 1], items[j]

优化一(判断对象有序,提前结束循环)

类似于:[9, 1, 2, 3, 4, 5, 6, 7, 8] 这样的部分有序待排序数组,使用原始冒泡发现除了第一次,之后均为无效操作。观察发现,当一次比较之后,如果没有发生交换行为,则认为该对象已经有序,便可提前结束循环。

  1. def bubble_sort(items):
  2. """冒泡排序 - O(N**2) """
  3. for i in range(1, len(items)):
  4. for j in range(0, len(items) - i):
  5. swapped = False
  6. if items[j] > items[j + 1]:
  7. items[j], items[j + 1] = items[j + 1], items[j]
  8. swapped = True
  9. if not swapped:
  10. break

优化二(解'>'的耦合,扩大函数使用范围)

类似于 {'Lucy':20,'Hope':18, 'Anna':23, 'Tom':66} 的数据经过方式一优化的冒泡仍然不能适用。究其原因是由于判断时运算符耦合所引起的参数对象类型错误,通过隐函数的方式解耦合即可解决。(参数说明:*之前的为位置参数,之后的为命名关键字参数)

  1. def bubble_sort(origin_items, *, comp=lambda x, y: x > y):
  2. """冒泡排序 - O(N**2) """
  3. for i in range(1, len(items)):
  4. for j in range(0, len(items) - i):
  5. swapped = False
  6. if comp(items[j], items[j + 1]):
  7. items[j], items[j + 1] = items[j + 1], items[j]
  8. swapped = True
  9. if not swapped:
  10. break

优化三(创建函数对象,避免对调用函数对象的修改)

观察Python内置的排序算法(sort:Timesort实现)发现调用函数本身不对对象进行修改,而是返回一个重新生成的对象,保留调用函数的对象。故而通过切片操作实现函数对象的生成。

  1. def bubble_sort(origin_items, *, comp=lambda x, y: x > y):
  2. """冒泡排序 - O(N**2) """
  3. items = origin_items[:]
  4. for i in range(1, len(items)):
  5. for j in range(0, len(items) - i):
  6. swapped = False
  7. if comp(items[j], items[j + 1]):
  8. items[j], items[j + 1] = items[j + 1], items[j]
  9. swapped = True
  10. if not swapped:
  11. break
  12. return items

优化四(双向比较,又称搅拌排序、鸡尾酒排序)

类似于 [9, 2, 3, 4, 5, 6, 7, 8, 1] 这样的待排序对象,可以看出如果正向依次排序之后再反向进行相邻比较,只需要两次之后,第三次即可根据判断有无发生交换提前结束循环,大大减小了运算的时间。

  1. def bubble_sort(origin_items, *, comp=lambda x, y: x > y, comp_back=lambda x, y: x < y,):
  2. """冒泡排序 - O(N**2) """
  3. items = origin_items[:]
  4. for i in range(1, len(items)):
  5. swapped = False
  6. for j in range(0, len(items) - i):
  7. if comp(items[j], items[j + 1]):
  8. items[j], items[j + 1] = items[j + 1], items[j]
  9. swapped = True
  10. for j in range( len(items) - i, 0, -1):
  11. if comp_back(items[j], items[j - 1]):
  12. items[j], items[j - 1] = items[j - 1], items[j]
  13. swapped = True
  14. if not swapped:
  15. break
  16. return items

简单排序(时间复杂度为O(N**2)的排序算法)中对冒泡排序面试面的最多,大概就是冒泡算法容易优化吧!而且优化之后也是相当便捷的o(* ̄︶ ̄*)o

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值