#工具人排序
def nums_sort(data):
if not data:
return []
min_data = min(data)
max_data = max(data)
nums = [0]*(max_data-min_data+1)
for value in data:
nums[value-min_data]+=1
cur = min_data
for index in range (len(data)):
while cur<= max_data and nums[cur-min_data]<=0:
cur+=1
nums[cur-min_data]-=1
data[index] = cur
return data
print(nums_sort(old_data[:]))
def bucket_sort(data,K = 10):
if not data:
return
#K桶的大小 桶的大小 = data的范围时,就一个桶,可以退化为计数排序
if K<=0:
K = 10
min_data = min(data)
max_data = max(data)
#//K向下取整,需要多补一个,计数排序返回空[]才可以用extend函数
buckets = [[] for _ in range(1+(max_data-min_data)//K)]
for value in data:
buckets[(value-min_data)//K].append(value)
res = []
for i in buckets:
res.extend(nums_sort(i))
return res
print(bucket_sort(old_data[:],K=2))
补充了排序彩蛋,我自己留着也没用。
#排序
old_data = [1,6,2,8,3,7,4,5,9]
#1选择排序,不稳定
#每次选择最小的与当前的开头交换
#时间O(1),O(n^2),O(n^2),空间O(1)
def selection_sort(data):
for st_index in range(len(data)):
min_data = data[st_index]
min_index = st_index
#最小值搜索
for j in range(st_index+1,len(data)):
if min_data>=data[j]:
min_data = data[j]
min_index = j
data[st_index],data[min_index]=data[min_index],data[st_index]
print(data)
selection_sort(old_data[:])
#2插入排序,稳定
#将当前数值插入到前面位置有序数组
#时间O(1),O(n^2),O(n^2),空间O(1)
def insert_sort(data):
for cur_index in range(1,len(data)):
cur_data = data[cur_index]
#插入
for j in range(cur_index,0,-1):
#如果后面的base数值比前面一个小,交换
#一直交换到大于前面的就好了
if cur_data>=data[j-1]:
break
data[j-1],data[j]=data[j],data[j-1]
print(data)
insert_sort(old_data[:])
#3希尔排序,不稳定
#插入快排的优化,插入要一个一个移动,希尔排序定义了数据间隔,从大到小,根据间隔插入
#适用性强,适合当base
#时间O(n),O(n^1.3-2),O(n^2),空间O(1)
def shell_sort(data,k=3):
d = 1
while d
d*=k
d+=1
while d>=1:
#正常的插入排序,间隔改成了由1改成d
for cur_index in range(d,len(data)):
cur_data = data[cur_index]
for j in range(cur_index,d-1,-d):
if cur_data>=data[j-d]:
break
data[j-d],data[j]=data[j],data[j-d]
d//=k
print(data)
shell_sort(old_data[:])
#归并排序,稳定
#时间O(nlog(n)),O(nlog(n)),O(nlog(n)),空间O(n)
#全局数组写法,实际上开临时数组写法更简略,空间复杂度都是O(n),主要担心频繁开小空间浪费时间,可读性不如后者
def merge(data,l1,r1,l2,r2,data_help):
cur_index = 0
t_l1,t_l2=l1,l2
while(l1<=r1 and l2<=r2):
if data[l1]<=data[l2]:
data_help[cur_index],cur_index,l1,=data[l1],cur_index+1,l1+1
else:
data_help[cur_index],cur_index,l2=data[l2],cur_index+1,l2+1
while(l1<=r1):
data_help[cur_index],cur_index,l1,=data[l1],cur_index+1,l1+1
while(l2<=r2):
data_help[cur_index],cur_index,l2=data[l2],cur_index+1,l2+1
l1,l2=t_l1,t_l2
for index in range(r1-l1+1):
data[l1+index]=data_help[index]
for index in range(r2-l2+1):
data[l2+index]=data_help[index+r1-l1+1]
def merge_sort(data,st = None,en = None):
if not data:
return None
if st is None:
st = 0
if en is None:
en = len(data)-1
merge_sort_help(data,st,en,[0]*(en-st+1))
def merge_sort_help(data,st,en,data_help):
if st
mid = st + (en-st)//2
merge_sort_help(data,st,mid,data_help)
merge_sort_help(data,mid+1,en,data_help)
merge(data,st,mid,mid+1,en,data_help)
#非递归,每次相邻合并一下即可,步长从1自增
def merge_bottom(data,st = None,en = None):
if not data:
return None
if st is None:
st = 0
if en is None:
en = len(data)-1
step = 1
data_help = [0]*(en-st+1)
while step<=en-st+1:
for left in range(st,en-step+1,2*step):
l1,r1,l2,r2 = left,left+step-1,left+step,left+2*step-1
if r2>en:
r2=en
merge(data,l1,r1,l2,r2,data_help)
step*=2
print(data)
merge_sort(old_data[:])
merge_bottom(old_data[:])
#快排,不稳定
#时间O(nlog(n)),O(nlog(n)),O(n^2),空间O(1)
#快排的优点就是快,主要是数据量比较大的时候
#三路快排
def q_sort(data,st=None,en=None):
if not data:
return
if st is None:
st = 0
if en is None:
en = len(data)-1
if st>=en:
return
import random
index = random.randint(st,en)
data[index],data[st]=data[st],data[index]
l,r = st+1,en
base = data[st]
#base的边界为r
index = st
while l<=r:
#左端点比叫base,小值则交换base和当前左端点,大值则当前左端点和尾端交换
#index代表了小于base的分界线,r代表大于base的分界线
if data[l]
data[index],data[l],index,l=data[l],data[index],index+1,l+1
continue
if data[l]>base:
data[l],data[r],r=data[r],data[l],r-1
continue
l+=1
q_sort(data,st,index-1)
q_sort(data,r+1,en)
return data
#非递归,展开即可,由于区域不想交,可以随机改顺序,只要排序范围逐渐减少就行
def q_sort_bottom(data,st=None,en=None):
if not data:
return
if st is None:
st = 0
if en is None:
en = len(data)-1
if st>=en:
return
import queue
q = queue.Queue()
q.put((st,en))
while(q.empty()==False):
cur = q.get()
st,en = cur[0],cur[1]
import random
index = random.randint(st,en)
data[index],data[st]=data[st],data[index]
l,r = st+1,en
base = data[st]
index = st
while l<=r:
#左端点比叫base,小值则交换base和当前左端点,大值则当前左端点和尾端交换
if data[l]
data[index],data[l],index,l=data[l],data[index],index+1,l+1
continue
if data[l]>base:
data[l],data[r],r=data[r],data[l],r-1
continue
l+=1
if st
q.put((st,index-1))
if r+1
q.put((r+1,en))
return data
print(q_sort(old_data[:]))
print(q_sort_bottom(old_data[:]))
#堆排序,不稳定
#时间O(nlog(n)),O(nlog(n)),O(nlog(n)),空间O(n)
#建堆O(n),但是顺序要从堆中一个个弹出,这一步是O(nlog(n))
#更新调整操作
#小值在前用大顶堆
def heap_adj(data,index):
if not data:
return
if index<0 or index>=len(data):
return
l,r = index*2+1,index*2+2
cur = index
if l
cur = l
if r
cur = r
if cur!=index:
data[index],data[cur]=data[cur],data[index]
heap_adj(data,cur)
return
#原地建堆
def make_heap(data):
for index in range(len(data)//2,-1,-1):
heap_adj(data,index)
heap = data
return heap
def heap_updata(heap,value):
if heap is None:
return
if value
heap[0]=value
heap_adj(heap,0)
def heap_delete(heap):
if heap is None:
return
heap[0]=heap[-1]
heap.pop()
heap_adj(heap,0)
def heap_add(heap,value):
heap.append(value)
index = len(heap)-1
next_index = (index-1)//2
while index!=next_index and index>=0:
if data[index]>data[next_index]:
data[index],data[next_index]=data[next_index],data[index]
index,next_index=next_index,(next_index-1)//2
continue
else:
break
return
def heap_sort(data):
heap = make_heap(data[:])
#大顶堆
times = len(heap)
res = [0]*times
for index in range(times-1,-1,-1):
res[index]=heap[0]
heap_delete(heap)
return res
print(heap_sort(old_data[:]))
#桶排序 = 分段计数排序
#计数排序,统计各个元素的数目
def nums_sort(data):
if not data:
return []
min_data = min(data)
max_data = max(data)
nums = [0]*(max_data-min_data+1)
for value in data:
nums[value-min_data]+=1
cur = min_data
for index in range (len(data)):
while cur<= max_data and nums[cur-min_data]<=0:
cur+=1
nums[cur-min_data]-=1
data[index] = cur
return data
print(nums_sort(old_data[:]))
def bucket_sort(data,K = 10):
if not data:
return
#K桶的大小 桶的大小 = data的范围时,就一个桶,可以退化为计数排序
if K<=0:
K = 10
min_data = min(data)
max_data = max(data)
#//K向下取整,需要多补一个,计数排序返回空[]才可以用extend函数
buckets = [[] for _ in range(1+(max_data-min_data)//K)]
for value in data:
buckets[(value-min_data)//K].append(value)
res = []
for i in buckets:
res.extend(nums_sort(i))
return res
print(bucket_sort(old_data[:],K=2))