这里写自定义目录标题
插入排序
直接插入排序
- 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率
步骤:将第一待排序序列第一个元素看做一个有序序列,把第二个元素到最后一个元素当成是未排序序列。
从头到尾依次扫描未排序序列,将扫描到的每个元素插入有序序列的适当位置。
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定
def insertionSort(arr):
for i in range(len(arr)):
preIndex = i-1
current = arr[i]
while preIndex >= 0 and arr[preIndex] > current:
arr[preIndex+1] = arr[preIndex]
preIndex-=1
arr[preIndex+1] = current
return arr
希尔排序
递减增量排序算法
步骤:按照增量d分组排序,d1=n//2,d2=d1//2,……
对于i in [0,d1),对data[i],data[i+d1],data[i+2*d1]……做插入排序
然后d2,d3……直到d==1,对整个表做一次插入排序
时间复杂度:O(n^1.3)
空间复杂度:O(1)
稳定性:不稳定
def shellSort(arr):
n=len(arr)
d=n//2
while d>=1:
print(d)
for i in range(0,d):#有这些个子序列需要排序 i代表了需要遍历的子序列的第一个
for j in range(i+d,n,d):#j表示当前要插入的点
pre=j-d#pre表示可能要后移的点
temp=arr[j]
while pre>=i and arr[pre]>temp:
arr[pre+d]=arr[pre]
pre-=d
arr[pre+d]=temp
d=d//2
#print(arr)
return arr
交换排序
冒泡排序
步骤:不断比较两个相邻元素,每趟比较后,最大的到了最右端
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:稳定
def bubbleSort(arr):
n=len(arr)
for i in range(0,n):
for j in range(1,n-i):
if arr[j]<arr[j-1]:
#print('change',arr[j], arr[j -1])
arr[j], arr[j -1] = arr[j - 1], arr[j]
print(arr)
return arr
快速排序
步骤:随机选取一个元素作为轴,小于或者等于它的放左边,大于它的放右边,再接着处理左边和右边
时间复杂度:平均O(nlogn), 最坏O(n^2)
空间复杂度:最好O(logn), 最坏O(n)
稳定性:no
def partition(arr,l,r):
temp=arr[l]
while l<r:#等于的时候即为找到中轴了
while l<r and arr[r]>temp:
r-=1
arr[l]=arr[r]
while l<r and arr[l]<=temp:
l+=1
arr[r]=arr[l]
arr[l]=temp
return l
def partition2(arr,l,r):
temp=arr[l]
ln,rn=l,r
while ln<=rn:
#有等于号是为了让left<right,并且让right指到一个<=temp的位置,从而和中轴值换位置
while ln<=rn and arr[rn]>temp:
rn-=1
while ln<=rn and arr[ln]<=temp:
ln+=1
if ln<rn:
arr[ln],arr[rn]=arr[rn],arr[ln]
ln+=1
rn-=1
arr[l],arr[rn]=arr[rn],arr[l]
return rn
def quickSort(arr, left, right):
if left<right:
p=partition2(arr,left,right)
quickSort(arr, left, p-1)
quickSort(arr, p+1, right)
选择排序
简单选择排序
步骤:每次找出一个最小的来,和位置i-1的值交换
时间复杂度:O(n^2)
空间复杂度:O(1)
稳定性:
def SelectionSort(arr):
for i in range(1,len(arr)):
k=i-1
for j in range(i,len(arr)):
if arr[j]<arr[k]:
k=j
if k!=i-1:
arr[i-1],arr[k]=arr[k],arr[i-1]
return arr
堆排序
步骤:
时间复杂度:O(nlogn)
空间复杂度:O(1)
稳定性:no
归并排序
步骤:分治法
时间复杂度:O(nlogn)
空间复杂度:O(n)
稳定性:yes
def mergeSortm(arr):
n=len(arr)
if n<2:
return arr
mid=n//2
leftarr,rightarr=arr[0:mid],arr[mid:]
return mergem(mergeSort(leftarr),mergeSort(rightarr))
def mergem(leftarr,rightarr):
llen=len(leftarr)
rlen=len(rightarr)
result=[]
li,ri=0,0
for k in range(llen+rlen):
if li==llen:
while ri<rlen:
result.append(rightarr[ri])
ri+=1
break
elif ri==rlen:
while li<rlen:
result.append(rightarr[li])
li+=1
break
if leftarr[li]<=rightarr[ri]:
result.append(leftarr[li])
li+=1
else:
result.append(rightarr[ri])
ri+=1
计数排序
步骤: 统计给个值的个数,存在数组相应的下标中
时间复杂度: O(n+k)
空间复杂度: O(n+k)
稳定性: 稳定
当输入的元素是 n 个 0 到 k 之间的整数时,它的运行时间是 Θ(n + k)。计数排序对于数据范围很大的数组,需要大量时间和内存。
def countingSort(arr, maxValue):
bucketLen = maxValue+1
bucket = [0]*bucketLen
sortedIndex =0
arrLen = len(arr)
for i in range(arrLen):
#if not bucket[arr[i]]:
#bucket[arr[i]]=0
bucket[arr[i]]+=1
for j in range(bucketLen):
while bucket[j]>0:
arr[sortedIndex] = j
sortedIndex+=1
bucket[j]-=1
return arr
桶排序
步骤:
时间复杂度: O(n)
空间复杂度: O(m)
稳定性:稳定
def bucktetSort(numList,bucketNum):
if len(numList) == 0 or len(numList) == 1:
return numList
maxNum = numList[0]
minNum = numList[0]
for i in range(1,len(numList)): # max and min value
if numList[i] < minNum:
minNum = numList[i]
elif numList[i] > maxNum:
maxNum = numList[i]
else:
continue
bucketSize = (maxNum - minNum + 1) // bucketNum
# range
buckets = [[] for i in range(bucketNum)]
for i in range(len(numList)):
buckets[(numList[i] - minNum) // bucketSize].append(numList[i])
for i in range(bucketNum):
buckets[i].sort()
res = []
for i in range(len(buckets)):
for j in range(len(buckets[i])):
res.append(buckets[i][j])
return res
numlist = [11,34,23,56,8,20,66,45,54,87,78]
print(bucktetSort(numlist,5))
基数排序
步骤: 基数排序是对桶排序的扩展。
第一类:最低位优先法,简称LSD法:先从最低位开始排序,再对次低位排序,直到对最高位排序后得到一个有序序列;
第二类:最高位优先法,简称MSD法:先从最高位开始排序,再逐个对各分组按次高位进行子排序,循环直到最低位。(位没有数的话,补0)
时间复杂度: O(k*n)
空间复杂度: O()
稳定性:稳定
def getbit(num,i): #
return (num % (i * 10) - (num % i)) // i
def getMax(numList): #
if len(numList) == 1:
return numList[0]
maxNum = numList[0]
for i in range(len(numList)):
if numList[i] > maxNum:
maxNum = numList[i]
return maxNum
def radixSort(numList):
if len(numList) == 0 or len(numList) == 1:
return numList
maxNum = getMax(numList)
bitCount = 0
index = 1
while maxNum // index:
bitCount += 1
index *= 10
currentBit = 1
# maxvalue's bitCount
while currentBit <= 10**(bitCount-1):#
res = []
buckets = [[] for i in range(10)] #
for i in numList:
currentBitNum = getbit(i,currentBit)
buckets[currentBitNum].append(i)
for i in range(10):
for j in range(len(buckets[i])):
res.append(buckets[i][j])
numList = res
currentBit *= 10
return numList
numlist = [12,3,45,3543,214,1,4553]
print(radixSort(numlist))