自己本来照着《算法导论》提供的思路折腾了一个函数,可是,一经10w数据测试,就发现自己还是太年轻,too yong,too simple,慢得掉渣。只得去找因特网上先行者们留下的代码了,算法导论之...,再次膜拜大牛们
不经优化的方法:
sys.setrecursionlimit(1000000000)
def quick_sort(array, l, r):
if l < r:
q =partition(array, l, r)
quick_sort(array, l, q - 1)
quick_sort(array, q + 1, r)
def partition(array, l, r):
x = array[r]
i = l - 1
for j in range(l, r):
if array[j] <= x:
i += 1
array[i], array[j] = array[j], array[i]
array[i + 1], array[r] = array[r], array[i+1]
return i + 1
经5分法取中位数优化后:
def insertion_sort(a_list):
last=len(a_list)-1
if last>0:
a_list1=insertion_sort(a_list[:last])
i=len(a_list1)-1
temp=a_list[last]
while i>=0:
if temp<=a_list1[i]:
i-=1
else:
break
for pos in range(last,i+1,-1):
a_list[pos]=a_list1[pos-1]
a_list[i+1]=temp
a_list[:i+1]=a_list1[:i+1]
return a_list
def partition2(a_list,key):
p=a_list.index(key) #Question: such an enbarrasing thing to find the key from a_list, how to do?
pivot=a_list[p]
a_list[p]=a_list[0]
a_list[0]=pivot
i=0
j=1
while j<len(a_list):
if a_list[j]<pivot:
i+=1
a_list[i],a_list[j]=a_list[j],a_list[i]
j+=1
a_list[0],a_list[i]=a_list[i],a_list[0]
return (i+1,a_list[:i],a_list[i+1:])
def mid_select(a_list):
if len(a_list)>5:
k=(len(a_list)+1)//2
a_list_next=a_list[:]
base=0
while a_list_next !=[]:
a_list_mid =[]
for i in range(len(a_list_next)//5):
a_list_part=a_list_next[5*i:5*(i+1)]
a_list_order=insertion_sort(a_list_part)
mid_part=a_list_order[2]
a_list_mid.append(mid_part)
if len(a_list_next)%5 !=0:
a_list_part=a_list_next[5*(len(a_list_next)//5):]
a_list_order=insertion_sort(a_list_part)
mid_part =a_list_order[(len(a_list_order)+1)//2-1]
a_list_mid.append(mid_part)
mid= mid_select(a_list_mid)
i,a_list_left,a_list_right = partition2(a_list_next,mid)
i =base +i # revise the index of mid in the original a_list
if i==k:
return mid
elif i <k:
a_list_next=a_list_right
base =i
else:
a_list_next=a_list_left
return False
else:
a_list_order=insertion_sort(a_list)
return a_list_order[(len(a_list)+1)//2-1]
经主函数调用:
if __name__=='__main__':
N=100000
nums=[]
for i in range(N,0,-1):#随机序列输入就不Demon了,性能差不多;这里就设下最坏情况下的序列之一了---有序序列
#n=random.randint(1,100000000)
nums.append(i)
start=time.clock()
mid_select(nums)
#quick_sort(nums,0,len(nums)-1)
end=time.clock()
print('time is',end-start)
Demon:
10w有序输入数据:
结果是:经优化后快排处理10w有序输入数据仍然性能未减,而未经优化下算得计算机死机,n^2的复杂度,10w的平方为10的12次方