准备工作
所谓 “磨刀不误砍柴工”,在进行排序算法练习的时候,我们需要做一些准备的工作:
- 生成算法需要的数列:随机数列
- 对于一些极端情况,考虑算法的效率,需要生成基本有序的数列
- 测试算法性能的函数
- 判断数列是否有序
- 数列中元素相互交换
- 数列的拷贝
生成随机数列
#coding=utf-8
from random import randint
def generateRandomArray(n, min, max):
arr = []
arr = [randint(min, max) for x in range(n)]
return arr
生成基本有序的数列
def generateNearlyOrderedArray(n, swapTimes):
arr = []
for i in range(n):
arr.append(i)
for j in range(swapTimes):
posx = randint(0, n-1)
posy = randint(0, n-1)
arr[posx], arr[posy] = arr[posy], arr[posx]
return arr
判断数列是否有序(算法是否正确)
def isSorted(alist):
for i in range(0, len(alist)-1):
if alist[i] > alist[i+1]:
return False
return True
测试算法性能(耗费时间)
t1 = timeit.Timer('testSort("某种排序算法函数", alist)', 'from __main__ import testSort, 某种排序算法函数, alist')
print('某种排序算法:%s s' %t1.timeit(number=1))
# func表示要检测的算法函数,alist为传入的数列
def testSort(func, alist):
alist = func(alist)
assert isSorted(alist), "排序算法错误\n"
数列中元素相互交换
Python 语言对于交换两个数列的元素非常简单:
alist[i], alist[j] = alist[j], alist[i]
数列的拷贝
对于数列的拷贝,在 Python 语言中可以直接使用数列的切片:
# 直接使用切片
# list = [8,6,2,3,1,5,7,4]
alist=list[:]
冒泡排序
算法思想
冒泡排序要对一个列表多次重复遍历。它要比较相邻的两项,并且交换顺序排错的项。每对 列表实行一次遍历,就有一个最大项排在了正确的位置。大体上讲,列表的每一个数据项都会在 其相应的位置 “冒泡”。如果列表有 n 项,第一次遍历就要比较 n-1 对数据。需要注意,一旦列 表中最大(按照规定的原则定义大小)的数据是所比较的数据对中的一个,它就会沿着列表一直 后移,直到这次遍历结束。
代码实现
# 冒泡排序
def bubbleSort(alist):
n = len(alist)
for i in range(n-1, 0, -1):
for j in range(0, i):
if alist[j] > alist[j+1]:
alist[j], alist[j+1] = alist[j+1], alist[j]
return alist
优化点
因为冒泡排序必须要在最终位置找到之前不断交换数据项,所以它经常被认为是最低效的排 序方法。这些 “浪费式” 的交换操作消耗了许多时间。但是,由于冒泡排序要遍历整个未排好的 部分,它可以做一些大多数排序方法做不到的事。尤其是如果在整个排序过程中没有交换,我们就可断定列表已经排好。因此可改良冒泡排序,使其在已知列表排好的情况下提前结束。这就是说,如果一个列表只需要几次遍历就可排好,冒泡排序就占有优势:它可以在发现列表已排好时立刻结束。
优化代码
# 冒泡排序
def bubbleSort(alist):
n = len(alist)
exchange = False
for i in range(n-1, 0, -1):
for j in range(0, i):
if alist[j] > alist[j+1]:
alist[j], alist[j+1] = alist[j+1], alist[j]
exchange = True
# 如果发现整个排序过程中没有交换,提前结束
if not exchange:
break
return alist
有帮助到你的点赞、收藏一下吧
需要更多教程,微信扫码即可
👆👆👆
别忘了扫码领资料哦【高清Java学习路线图】
和【全套学习视频及配套资料】