算法详细过程参考:https://www.cnblogs.com/onepixel/articles/7674659.html
1.冒泡排序:每次交换相邻的两个元素,大的放到后面,这样一次遍历后最大元素会放到队尾。
def bubble(array):
for i in range(len(array)):
for j in range(1,len(array)-i):
if array[j]< array[j-1]:
array[j],array[j-1]=array[j-1],array[j]
return array
2.选择排序:先选出最小的元素放在第一个位置,然后选出次小的放在第二个位置,依次类推。
def select(array):
for i in range(len(array)):
for j in range(i,len(array)):
if(array[j]<array[i]):
array[i],array[j]=array[j],array[i]
return array
3.插入排序:像玩牌一样,将每个元素放到比它小的元素的后面,代码实现是记录下当前元素,如果前面的元素比当前元素大则将前面的元素后移。
def insert(array):
for i in range(1,len(array)):
j=i
curr=array[i]
while j>0 and array[j-1]>curr:
array[j]=array[j-1]
j-=1
array[j]=curr
return array
4.希尔排序:是插入排序的改进版,第一个突破 O(n2) O ( n 2 ) 的算法,先进行大步长的插入排序,再进行小步长的插入排序,最后是1步长的插入排序
def shell(array):
k=1
while k<len(array)/3:
k=3*k+1
while k:
for i in range(k,len(array)):
j=i
curr=array[i]
while j>0 and array[j-k]>curr:
array[j]=array[j-k]
j-=k
array[j]=curr
k=math.floor(k/3)
return array
5.归并排序:分治思想,先将数组拆分,然后对拆分后的数组进行归并。也就是一直拆分到每个数组只有一个数,然后开始合并,合并的过程进行排序。
def merge_sort(array):
def merge(left,right):
i=0;j=0
result=[]
while i<len(left) and j<len(right):
if left[i]<right[j]:
result.append(left[i])
i+=1
else:
result.append(right[j])
j+=1
while i<len(left):
result.append(left[i])
i+=1
while j<len(right):
result.append(right[j])
j+=1
return result
if len(array)<=1:
return array
mid=len(array)//2
left=merge_sort(array[:mid])
right=merge_sort(array[mid:])
return merge(left,right)
6.快速排序:是对冒泡排序的改进,是一种二分思想。每次选一个基准数,比它小的放在左边,比它大的放在右边,从左边选一个比基准大的,从右边选一个比基准小的,将两者交换。快速排序每一轮处理的是将这一轮的基准数放到正确的位置。
def quick(array):
def sort(left,right,array):
if left>right:
return
i=left
j=right
key=array[left]
while i!=j:
while array[j]>=key and i<j:
j-=1
while array[i]<=key and i<j:
i+=1
if i<j:
a[i],a[j]=a[j],a[i]
a[left],a[i]=a[i],a[left]
sort(left,i-1,array)
sort(i+1,right,array)
sort(0,len(array)-1,array)
return array
7.堆排序:首先构建堆,时间复杂度是 O(n) O ( n ) ,然后有点类似于选择排序,每次从堆里将最小的数并入到排好序的子数组后面进行堆调整,再将最小的取出来。
def MAX_Heapify(heap,HeapSize,root):#在堆中做结构调整使得父节点的值大于子节点
left = 2*root + 1
right = left + 1
larger = root
if left < HeapSize and heap[larger] < heap[left]:
larger = left
if right < HeapSize and heap[larger] < heap[right]:
larger = right
if larger != root:#如果做了堆调整则larger的值等于左节点或者右节点的,这个时候做对调值操作
heap[larger],heap[root] = heap[root],heap[larger]
MAX_Heapify(heap, HeapSize, larger)
def Build_MAX_Heap(heap):#构造一个堆,将堆中所有数据重新排序
HeapSize = len(heap)#将堆的长度当独拿出来方便
for i in range((HeapSize -2)//2,-1,-1):#从后往前出数
MAX_Heapify(heap,HeapSize,i)
def HeapSort(heap):#将根节点取出与最后一位做对调,对前面len-1个节点继续进行对调整过程。
Build_MAX_Heap(heap)
for i in range(len(heap)-1,-1,-1):
heap[0],heap[i] = heap[i],heap[0]
MAX_Heapify(heap, i, 0)
return heap
8.计数排序:线性排序,需要开辟额外的数组,只能排整数
def countingSort(alist,k):
n=len(alist)
b=[0 for i in range(n)]
c=[0 for i in range(k+1)]
#统计每个数出现的次数
for i in alist:
c[i]+=1
#计算每个数应放在数组的哪个位置
for i in range(1,len(c)):
c[i]=c[i-1]+c[i]
for i in alist:
b[c[i]-1]=i
c[i]-=1
return b
9.桶排序:桶排序是计数排序的升级版,利用了函数的映射关系,当数据分布均匀时,可以将每一个数映射到桶内,桶内的数据进行排序,高效与否取决于映射关系。当数据分布不均匀时,建立最大值-最小值数目的桶。
def bucket(array):
max_value=max(array)
min_value=min(array)
s=[0 for i in range(min_value,max_value+1)]
#统计重复的数出现的个数
for i in array:
s[i-min_value]+=1
current=min_value
n=0
for i in s:
while i>0:
array[n]=current
i-=1
n+=1
#s里面有很多0,current的值是递增上去的
current+=1
return array
区间[0,1)均匀分布的桶排序
def sort(a):
def insert(array):
for i in range(1, len(array)):
j = i
curr = array[i]
while j > 0 and array[j - 1] > curr:
array[j] = array[j - 1]
j -= 1
array[j] = curr
n=len(a)
s=[[] for i in range(n)]
for i in a:
s[int(i/n)].append(i)
for i in s:
insert(i)
return [i for j in s for i in j]
10.基数排序:基数排序是按照低位先排序,然后收集;再按照高位排序,然后再收集;依次类推,直到最高位。有时候有些属性是有优先级顺序的,先按低优先级排序,再按高优先级排序。最后的次序就是高优先级高的在前,高优先级相同的低优先级高的在前。
基于桶排序的基数排序
def RadixSort(list,d):
for k in range(d):#d轮排序
s=[[] for i in range(10)]#因为每一位数字都是0~9,故建立10个桶
for i in list:
s[i//(10**k)%10].append(i) #977/10=97(小数舍去),87/100=0
list=[j for i in s for j in i]
return list
附录:排序算法复杂度