冒泡排序
冒泡排序(Bubble Sort)是一种很原始的排序方法,就是通过不断地交换“大数”的位置达到排序的目的。 因为不断出现“大数”类似于水泡不断出现,因此被形象地称为冒泡算法。 冒泡算法的基本原理:比较相邻两个数字的大小。将两数中比较大的那个数交换到靠后的位置。 不断地交换下去就可以将最大的那个数放到队列的尾部。然后重头再次交换,直到将数列排成有序数列。
a=[5, 9, 3, 1, 2, 8, 4, 7, 6]
for i in range(len(a)-1):
for j in range(1,len(a)-i):
if a[j]<a[j-1]:
a[j],a[j-1]=a[j-1],a[j]
print(a)
冒泡排序原理:
1通过不断地交换“大数”的位置达到排序的目的
2冒泡排序的时间复杂度是O(n2)
选择排序
与冒泡排序相比,选择排序算法(Selection Sort)的原理更加简单粗暴,就是在数列中不断地找最小(大)的那个数。 选择排序算法的基本原理:从数列中选择最大(最小)的那个数,将这个数放到合适的位置,然后在删除这个数的子数列 中选择最大(最小)的那个数,将这个数放到合适的位置…直到子数列为空。
a=[5, 9, 3, 1, 2, 8, 4, 7, 6]
for i in range(len(a)-1):
for j in range(i+1,len(a)):
if a[j]<a[i]:
a[i],a[j]=a[j],a[i]
print(a)
选择排序原理:
1 不断将数列中的最小值交换到数列头部实现排序
2 选择排序的时间复杂度是O(n2)
插入排序
插入排序(Insertion Sort)很容易理解,插入排序方法与打扑克抓牌的排序很相似。在打扑克时,每抓一张新牌, 都会与手上已有的牌进行比较,**将新牌插入到比自己小的牌后面。**在取完所有的牌后,手上已有的牌就是个有序的序列。 插入排序原理:首先将数列分成两部分。数列的第一个数为left部分,其他的数为right部分。然后将right部分中的数逐一取出, 插入left部分中合适的位置。当right部分为空时,left部分就成为了一个有序数列。
a=[5, 9, 3, 1, 2, 8, 4, 7, 6]
for right in range(1,len(a)):
target=a[right]
for left in range(0,right):
if target<=a[left]:
a[left+1:right+1]=a[left:right]
a[left]=target
break
print(a)
插入排序原理:
1 将数列分成两部分,数列的第一个数为left部分, 其他的数为right部分
2 将right部分中的数逐一取出,插入left部分中合适 的位置
归并排序
归并排序(Merge Sort)是一种典型的递归法排序。它把复杂的排序过程分解成一个简单的合并子序列的过程。 归并排序原理:先将数列分成左右两份(最好是等分),然后将左、右子数列排序完毕后再合并到一起就成了一个有序数列 左、右两个子数列变成有序数列的过程是一个递归过程:再把子数列分成左、右两份,把子子数列排序完毕后合并成子数列…
a=[5, 9, 3, 1, 2, 8, 4, 7, 6]
def mergesort(l):
if len(l)<=1:
return l
mid=len(l)//2
return mergelist(mergesort(l[0:mid]),mergesort(l[mid:]))
def mergelist(left,right):
b=[]
while (left and right):
if left[0]>=right[0]:
b.append(right.pop(0))
else:
b.append(left.pop(0))
while left:
b.append(left.pop(0))
while right:
b.append(right.pop(0))
return b
print(mergesort(a))
归并排序原理:
1 将数列不断分成两组直到不能再分,在合并时排序
2 归并排序的时间复杂度是O(nlogn)
快速排序
快速排序(Insertion Sort)也是一种递归排序算法。 快速排序原理 :先以列表中的任意一个数为基准(一般选头或尾),将列表分为左、右两个子列表: 左子列表的数要比基准数小,右子列表的数要比基准数大。然后继续把左子列表和右子列表按同样的方法继续分解、 比较,直到分无可分。最后将左子列表(比基准数小)+基准数+右子列表(比基准数大)连接起来得到一个有序数列。
def quickSort(input_list,left,right):
def sortlist(input_list,left,right):
temp=input_list[right]
i,j=left,right-1
while i<=j:
while i<=j and input_list[j]>=temp:
j-=1
while i<=j and input_list[i]<=temp:
i+=1
if i<j:
input_list[i],input_list[j]=input_list[j],input_list[i]
input_list[right],input_list[i]=input_list[i],input_list[right]
return i
if left<right:
index=sortlist(input_list,left,right)
quickSort(input_list,index+1,right)
quickSort(input_list,left,index-1)
if __name__=='__main__':
input_list = [6, 4, 8, 9, 2, 3, 1]
a=input(" shuru");
b=[10];
print('排序前:', input_list)
quickSort(input_list,0,len(input_list)-1)
print('排序后:', input_list)
桶排序
桶排序(Bucket Sort)是核心思想是将要排序的数据分到有限个有序的桶中,每个桶里的数据再单独进行排序。 桶内排序之后,再把每个桶里的数据按照桶的顺序依次取出,得到有序数列。
桶排序(Bucket Sort)适用于待排序数据值域较大但分布比较均匀的情况。
按下列步骤进行:
1.设置一个定量的数组当作空桶;
2.遍历序列,并将元素一个个放到对应的桶中;
3.对每个不是空的桶进行排序;
4.从不是空的桶里把元素再放回原来的序列中。
a=[5, 9, 3, 1, 2, 8, 4, 7, 6]
max_value=max(a)
size=max_value/len(a)
bucket_list=[[] for _ in range(len(a))]
for i in range(len(a)):
j=a[i]//size
if j!=len(a):
bucket_list[j].append(a[i])
else:
bucket_list[len(a)-1].append(a[i])
for z in range(len(a)):
##使用插入排序
for right in range(1,len(bucket_list[z])):
target=bucket_list[z][right]
for left in range(right):
if bucket_list[z][left]>target:
bucket_list[z][left+1:right+1]=bucket_list[z][left:right]
bucket_list[z][left]=target
output_list=[]
for x in range(len(a)):
output_list+=bucket_list[x]
print(output_list)
时间复杂度
由于每个桶内元素不多,一般桶内排序使用插入排序。此时桶排序是一种稳定的排序算法。 桶排序的平均时间复杂度为 O(n+n2/k+k)(将数据平均分成N块 + 排序 + 重新合并元素),当K≈n时为 O(n) 桶排序的最坏时间复杂度取决于桶内排序的算法
桶排序应用场景
桶排序(Bucket Sort)对要排序的数据要求较多。
1 要排序的数据需要很容易就能划分成 N 个桶,并且,桶与桶之间有着天然的大小顺序
2 数据在各个桶之间的分布最好比较均匀。否则可能出现,有些桶里的数据非常多,有些非常少,极端情况可能会被 划分到同一个桶中
桶排序(Bucket Sort)比较适合用在外部排序中。
1 10G的邮件地址数据按地址字典序排序, 几百M内存
2 桶排序思想, 100M一个文件
堆排序
堆排序(Heap Sort)是利用堆数据结构进行排序的算。
堆数据结构:堆是一种特殊的树,那么什么样的树才是堆?
1 堆是一个完全二叉树
2 堆中每一个节点的值都必须大于等于(或小于等于)其子树中每个节点的值