冒泡排序法又称为交换排序法,是从观察水中气泡变化构思而成。原理是从第一个元素开始,比较相邻元素的大小,若大小顺序有误,则对调后再进行下一个元素的比较。如此经过第一次扫描后就可以确保最后一个元素位于正确的顺序;经过第二次扫描可以确保倒数第二个元素位于正确的顺序。由此可知,N个元素经过(N-1)次扫描,就可以完成所有元素的排序。
下面使用55、23、87、62、16数列来演示排序过程,这样大家可以清楚地知道冒泡排序法的具体流程。从小到大排序,原始顺序如图:
下面设计一个python程序,并使用冒泡排序法来对数列进行从小到大的排序。
读入原始数列:
data = [55, 23, 87, 62, 16] #原始数据
data_len = len(data) #原始数据长度
print('原始数据为:')
for i in range(data_len):
print('%d' %data[i], end=' ')
使用冒泡排序法排序:
for i in range(data_len-1, 0, -1): #扫描次数,共4次,(4,3,2,1)
for j in range(i):
if data[j] > data[j+1]: #比较,交换
data[j], data[j+1] = data[j+1], data[j] #比较相邻两数,如果第一数较大则交换
print('第%d次排序后的结果是:'%(data_len-i), end=' ') #把各次扫描后的结果打印出来
for j in range(data_len):
print('%d' %data[j], end=' ')
print()
print('排序后的结果为:')
for j in range(data_len):
print('%d' %data[j], end=' ')
选择排序法(Selecting Sort)也算是枚举法的应用,就是反复从未排序的数列中取出最小的元素,加入到另一个数列中,最后的结果即为已排序的数列。从小到大排序的操作是一开始在所有的数据中挑选一个最小项放在第一个位置,再从第二项开始挑选剩下元素的最小项放在第2个位置,以此反复,直到完成排序为止。由此可知,N个元素经过(N-1)次扫描,就可以完成所有元素的排序。
下面使用55、23、87、62、16数列从小到大的排序过程来说明选择排序法的演算流程。原始数据如图:
下面设计一个python程序,并使用选择排序法对数列进行从小到大的排序
读入原始数列:
data = [55, 23, 87, 62, 16] #原始数据
data_len = len(data) #原始数据长度
print('原始数据为:')
for i in range(data_len):
print('%d' %data[i], end=' ')
使用选择排序法排序:
def select(data):
for i in range(data_len-1):
for j in range(i+1, data_len):
if data[i] > data[j]: #比较第i和第j个元素
data[i], data[j] = data[j], data[i]
排序后的结果为:
select(data)
print('排序后的结果为:')
for j in range(data_len):
print('%d' %data[j], end=' ')
插入排序法(Insert Sort)是将数组中的元素,逐一与已排序好的数据进行比较,前两个元素先排好,再将第三个元素插入适当的位置,所以这三个元素仍然是已排好序的,接着将第四个元素加入,重复此步骤,直到排序完成为止。可以看作是在一串有序的记录R1、R2…Ri中,插入新的记录R,使得i+1个记录排序妥当。
下面我们仍然使用55、23、87、62、16数列从小到大的排序过程来说明插入排序法的演算流程。如下图所示,在步骤一种,以23为基准与55比较后,放到55的前面。步骤二则拿87与其他两个元素(23、55)比较。步骤三62在比较完前三个数后插入到87的前面……,步骤四将最后一个元素比较完成后即完成排序。由此可知,N个元素经过(N-1)个步骤,即可完成所有元素的排序。
下面设计一个python程序,并使用插入排序法进行从小到大的排序。
读入原始数据:
data = [55, 23, 87, 62, 16] #原始数据
data_len = len(data) #原始数据长度
print('原始数据为:')
for i in range(data_len):
print('%d' %data[i], end=' ')
使用插入排序法排序:
def insert(data):
for i in range(1, data_len):
tmp = data[i] #tmp用来暂存数据
NO = i - 1
while NO >= 0 and tmp < data[NO]:
data[NO+1] = data[NO] #就把所有比tmp大的元素往后推一个位置,此步骤是由后往前比较后并插入
NO -= 1
data[NO+1] = tmp #插入的位置
排序后的结果为:
insert(data)
print('排序后的结果为:')
for j in range(data_len):
print('%d' %data[j], end=' ')
当原始记录的键值大部分已排好序的情况下,插入排序法会非常有效率,因为它不需要执行太多的数据搬移操作。“希尔排序法”是D.L.Shell在1959年7月所发明的一种排序法,可以减少插入排序法中数据搬移的次数,以加速排序的进行。排序的原则是将数据区分成特定间隔的几个小区块,以插入排序法排完区块内的数据后,再逐渐减少间隔的距离。
下面我们用63、92、27、36、45、71、58、7数列从小到大的排序过程来说明希尔排序法的演算流程。原始数据如下图所示。
data = [63,92,27,36,45,71,58,7] #原始数据
data_len = len(data) #原始数据长度
def showdata(data):
for i in range(data_len):
print('%d' %data[i], end=' ')
print('原始数组是: ')
showdata(data)
使用希尔排序法排序:
def shell(data):
k = 1 # 第k次排序过程
size = len(data)
jmp = size // 2 #向下取整,例如1//2等于0;jmp为设置间距的位移量
while jmp != 0:
for i in range(jmp, size): #i为扫描次数
tmp = data[i] #tmp用来暂存数据
j = i - jmp #以j来定位比较的元素
while tmp < data[j] and j >= 0: #插入排序法
data[j+jmp] = data[j]
j = j-jmp
data[jmp+j] = tmp
print('第%d次排序过程:'%k, end=' ')
k += 1
showdata(data)
print()
print('--------------------------------------')
jmp = jmp//2 #控制循环次数
shell(data)
合并排序法(Merge Sort)的工作原理是针对已排序好的两个或两个以上的数列(或数据文件),通过合并的方式,将其组合成一个大的且已排好序的数列(或数据文件)。
下面我们使用38、16、41、72、52、98、63、25数列从小到大的排序过程来说明合并排序法的基本演算流程,如下图所示。
上面展示的合并排序法例子是一种最简单的合并排序,又称为2路(2-way)合并排序。
步骤如下:
下面设计一个python程序,并使用合并排序法来排序。
读入数据:
data = [38,16,41,72,52,98,63,25] #原始数据
合并两个有序数列:
def merge(a, b):
c = []
h = j = 0
while j < len(a) and h < len(b):
if a[j] < b[h]:
c.append(a[j])
j += 1
else:
c.append(b[h])
h += 1
if j == len(a):
for i in b[h:]:
c.append(i)
else:
for i in a[j:]:
c.append(i)
return c
合并排序:
#递归法
def merge_sort(lists):
if len(lists) <= 1:
return lists
#二分列表
middle = len(lists)//2
left = merge_sort(lists[:middle])
right = merge_sort(lists[middle:])
return merge(left, right)
输出最终结果:
print (merge_sort(data))
最终结果是 [16, 25, 38, 41, 52, 63, 72, 98]。
快速排序(Quick Sort)是由C.A.Hoare所提出来的。快速排序法又称分割交换排序法,是目前公认最佳的排序法,也是使用“分而治之”(Divide and Conquer)的方式,先在数据中找到一个虚拟的中间值,并按此中间值将所有打算排序的数据分为两部分。其中,小于中间值的数据放在左边,大于中间值的数据放在右边,再以同样的方式分别处理左、右两边的数据,直到排序完为止。
快速排序的步骤:
(1) 选择基准值。
(2) 将数组分成两个子数组:小于基准值的元素和大于基准值的元素。
(3) 对这两个子数组进行快速排序。
算法简单描述:选择数组第一位元素位基准值,创建两个新数组,分别存放小于基准值和大于基准值的元素。然后这两个新数组递归进行上述操作,直到数组为空。然后将左右数组和基准值进行拼接。
下面设计一个python程序,并使用快速排序法来排序。
快速排序代码:
def quicksort(array):
if len(array) < 2:
# 基线条件:为空或只包含一个元素的数组是“有序”的
return array
else:
pivot = array[0]
# 由所有小于基准值的元素组成的子数组
less = [i for i in array[1:] if i <= pivot]
# 由所有大于基准值的元素组成的子数组
greater = [i for i in array[1:] if i > pivot]
return quicksort(less) + [pivot] + quicksort(greater)
输出排序结果:
data = [35,10,42,3,79,12,62,18,51,23] #原始数据
quicksort(data)
输出结果为 [3, 10, 12, 18, 23, 35, 42, 51, 62, 79]。
快速排序法图解过程可参考:
https://blog.csdn.net/qq_40941722/article/details/94396010