冒泡排序
1、算法原理和步骤
比较相邻的两个元素大小,从左往右遍历一遍(n个元素遍历n-1次),把最大的元素逐渐沉底
第一次 循环 ,最后比较 a【n-2】和a[n-1]
第i次循环 ,最后比较 a【n-i-1】和a【n-i】
所以先从0遍历到n-1,然后内部从0遍历到n-i-1;
时间复杂度0(n^2) 空间复杂度O(1),稳定
2、代码实现
n=int(input())
a=list(map(int,input().split()))
#外层循环从1到n-1;
for i in range(1,n):
#内层循环 从下标0,到下标n-i-1;
for j in range(n-i):
if a[j]>a[j+1]:
a[j],a[j+1]=a[j+1],a[j]
print(' ',join(map(str,a)))
选择排序
1算法原理和步骤
从左到右遍历一遍,先找到最小的元素,放在起始位置;然后重复这个步骤,从第2个,第3个,第4个,一直到n-1个;
外循环是从下标0到n-2,总共n-1次;
内循环从第i个一直到最后一个;找到最小的和第i个换一下;
时间复杂度O(n^2),空间复杂度O(1),
2、代码实现
n = int(input())
a =list (map(int,input().split()))
#外循环是从下标0到n-2,总共n-1次;
for i in range(n-1):
min_val=a[i]
min_idx=i
#内循环从第i个一直到最后一个;找到最小的和第i个换一下
for j in range(i,n):
if a[j]< min_val:
min_val=a[j]
min_idx=j
a[i],a[min_idx]=a[min_idx],a[i]
print(' ',join(map(str,a)))
桶排序
1、算法原理和步骤
1、初始化K个桶
2、遍历数据,把数据均匀分布到K个桶中
3、每个桶单独排序;(内部排序可以用一些简单算法)
4、最后拼接起来
要注意的是:要是元素均匀分布,而且尽量增加桶的数量,用空间来换时间;
2、代码实现
def Bucket_sort(a,bucketcount):
minval,maxval=min(a),max(a)
bucketsize=(maxval-minval+1)//bucketcount
res=[[] for i in range(bucketcount+1)]
ans=[]
for x in a:
idx = (x-minval)//bucketsize
res[idx].append(x)
for res_x in res:
res_x.sort()
ans+=res_x
n=int(input())
a= list(map(int,input().split()))
a=Bucket_sort(a,min(10001,n))
print(' ',join(map(str,ans)))
快速排序
1、算法原理和步骤
a列表,是一个【left,right】
假设基准值是left,下标设为idx=left+1,从left+1开始遍历到最后,找每个元素a[i],:如果a[i]<=基准值了,那么就跟idx元素互换,并且idx+=1;
然后将基准值和前半部分的最后一个数交换,那么就把整个部分分成了【left,mid-1】,【mid】,【mid+1,right】;
利用递归实现快速排序,然后对前半部分和后半部分进行递归。
时间复杂度O(nlog(n)),空间复杂度O(nlog(n)),不稳定
2、代码实现
#列表a,左端点left,右端点right
#【left,right】
def partition(a,left,right):
#1、设立基准值和下标值
idx=left+1
#2、从基准值后面遍历一遍,从left+1开始遍历到最后,找每个元素a[i],:如果a[i]<=基准值了,那么就跟idx元素互换,并且idx+=1;
for i in range(idx,right+1):
if a[i]<= a[left]:
a[i],a[idx]=a[idx],a[i]
idx+=1
#将基准值和前半部分的最后一个(idx-1)进行互换
a[left],a[idx-1]=a[idx-1],a[left]
#这样他就分成了三个部分 然后返回他的中间值的下标
return idx-1
#对【left,right】进行排序
def quicksort(a,left,right):
if left < right :
mid = partition(a,left,right) #按照基准值进行划分 ,分为三部分:【left,mid-1】,【mid】,【mid+1,right】
#将前半部分和后半部分进行递归排序
quicksort(a,left,mid-1)
quicksort(a,mid+1,right)
n=int(input())
a=list(map(int,input().split()))
quicksort(a,0,n-1)
print(' ',join(map(str,a)))
归并排序
1、算法的原理和步骤
终拆成两个数进行比较,然后不断合并,合并成两个数组,然后归并排序
2、每一部分进行递归处理,先进行拆分,然后合并,这之间不断用到归并排序
3、归并排序的实现:
1、构建一个结果列表res=【】;
2、在A,B非空的前提下,比较A[0]和B【0】;将较小的放入res里面,然后弹出;一直比较,最后剩一个元素,把剩下的那一个加到res里面即可
2、代码实现
#合并两个列表A,B
def Merge(A,B):
res=[]
while len(A)!= 0 and len (B)!=0:
if A[0] <= B[0]:
res.append(A.pop(A[0]))
else:
res.append(B.pop(B[0]))
res.extend(A)
res.extend(B)
#递归实现
def Mergesort(A):
if len(A) <2:
return A
mid =len(A) //2 #切片划分成左右两部分,然后进行的递归操作
left = Mergesort(A[:mid])
right = Mergesort(A[mid:])
return Merge(left,right)
n= int(input())
a= list(map(int,input().split()))
print(map(str,Mergesort(a)))
插入排序
1、算法原理和步骤
插入排序 相当于摸一张牌,从后往前找一个合适的位置插入,如果这张牌小,那么就从前往后挪,直到找到合适的位置
记录下标,将这个牌加进去
n张牌,比较n-1次;然后i对应的牌,从后往前找,如果j牌比i牌大,那么就往后挪,如果小,那么j+1的位置就是对应i牌要插入的位置
2、代码实现
n=int(input())
a=list(map(int,input().split()))
#插入排序 相当于摸一张牌,从后往前找一个合适的位置插入,如果这张牌小,那么就从前往后挪,直到找到合适的位置,
#记录下标,将这个牌加进去
#n张牌,比较n-1次;然后i对应的牌,从后往前找,如果j牌比i牌大,那么就往后挪,如果小,那么j+1的位置就是对应i牌要插入的位置
#但是直接插入会导致覆盖,所以要记录i牌对应的值和要插入的下标
value=a[i]
insert_idx = 0
for i in range(1,n):
for j in range(i-1,-1,-1):
if a[j] > value :
#往后挪
a[j+1]=a[j]
else:
a[j] <= value
insert_idx=j+1
break
#将a[i]插入对应的位置
a[insert_idx]=value
print(' ',join(map(str,a)))