使用Python實現的4種快速排序算法

  排序算法,整體來講就是選一個基準值,把小於基準值的分一撥,把大於基準值的分到另外一撥,而後遞歸。算法

  有區別的是,分區算法有差別,最直接的是,選個基準值,定義兩個列表(小值分區less和大值分區great),而後挨個比較,小的追加到less,大的追加到greatapp

  再有就是,選個基準值,先從右邊開始比,比基準值大的無論,比基準值小就和基準值換位置,換一次後,就去和左邊比,比基準值小的無論,比基準值大的又去換位置,略有些繞。less

  最後,還能夠不遞歸,經過把分區節點保存在棧裏來實現。dom

  

  1 # -*- coding: utf-8 -*-
  2 
  3 import numpy as np
  4 #1)依次對比arr[0]和其餘元素,比arr[0]小的話,就原地刪除,而後插入到arr[0]前面,基準值後移。大於等於,則不處理。而後遞歸
  5 #原地排序
  6 def quick_sort1(arr,left,right):
  7     
  8     if left>=right:
  9         return
 10     flag=left
 11     for i in range(left+1,right+1):
 12         if arr[flag]>arr[i]:
 13             temp=arr[i]
 14             del arr[i]
 15             arr.insert(flag,temp)
 16             flag+=1
 17     quick_sort1(arr,left,flag-1)
 18     quick_sort1(arr,flag+1,right)
 19 #2)基準值arr[0],對比全部元素,比它小就追加到less後面,比它大就追加到great後面,相等就追加到pivot後面,而後遞歸
 20 #返回排序後的列表
 21 def quick_sort2(arr):
 22     less=[]
 23     great=[]
 24     pivot=[]
 25     if len(arr)<=1:
 26         return arr
 27     else:
 28         p=arr[0]
 29         for i in arr:
 30             if i<p:
 31                 less.append(i)
 32             elif i>p:
 33                 great.append(i)
 34             else:
 35                 pivot.append(i)
 36         less=quick_sort2(less)
 37         great=quick_sort2(great)
 38         return less+pivot+great
 39 #2-2)基本思想同上,代碼更簡化
 40 def quick_sort22(arr):
 41     if len(arr)<=1:
 42         return arr
 43     else:
 44         return quick_sort22([i for i in arr[1:] if i<arr[0]])+[arr[0]]+quick_sort22([i for i in arr[1:] if i>=arr[0]])
 46 #2-3)思路同上,更簡化的版本
 47 quick_sort23=lambda xs:((len(xs)<=1 and [xs]) or [quick_sort23([x for x in xs[1:] if x<xs[0]])+[xs[0]]+quick_sort23([x for x in xs[1:] if x>=xs[0]])])[0]
 49 quick_sort24=lambda arr:arr if len(arr)<=1 else quick_sort24([x for x in arr[1:] if x<arr[0]])+[arr[0]]+quick_sort24([x for x in arr[1:] if x>=arr[0]])

      #lambda 參數:取值1,若是知足條件1,不然,取值2 51 52 53 #3)定義兩個函數:分區和排序。分區是要把列表元素移動位置,直到基準值arr[0]移到中間(左邊都比它小,右邊都比它大)。排序則調用分區並遞歸 54 #原地排序 55 def partition(arr,i,j): 56 p=arr[i] 57 while i!=j: 58 while i<j and p<=arr[j]:#此處添加=,解決了以前遇到的序列中有重複值時死循環的問題 59 j-=1 60 arr[i]=arr[j] 61 while i<j and p>arr[i]: 62 i+=1 63 arr[j]=arr[i] 64 arr[i]=p 65 return i 66 def quick_sort3(arr,i,j): 67 if i<j: 68 mid=partition(arr,i,j) 69 quick_sort3(arr,i,mid-1) 70 quick_sort3(arr,mid+1,j) 71 #3-2)上述思路的變體,分區函數變更,每次都比右邊是否比基準值大,大的話,j前移,不然,把arr[j]給到arr[i],而後i後移,arr[i]再給到arr[j],繼續上述循環 72 def partition2(arr,i,j): 73 p=arr[i] 74 while i!=j: 75 while i<j and p<=arr[j]: 76 j-=1 77 78 while i<j and p>arr[j]: 79 arr[i]=arr[j] 80 i+=1 81 arr[j]=arr[i] 82 arr[i]=p 83 return i 84 def quick_sort32(arr,i,j): 85 if i<j: 86 mid=partition2(arr,i,j) 87 quick_sort32(arr,i,mid-1) 88 quick_sort32(arr,mid+1,j) 89 #3-3)分區函數變更,基準值爲最後一個值,依次比較,若是比基準值小,就換到前面去,最後再把基準值換到中間。 90 def partition3(arr,i,j): 91 p=arr[j] 92 x=i-1 93 for y in range(i,j): 94 if arr[y]<=p: 95 x+=1 96 arr[x],arr[y]=arr[y],arr[x] 97 arr[x+1],arr[j]=arr[j],arr[x+1] 98 return x+1 99 def quick_sort33(arr,i,j): 100 if i<j: 101 mid=partition3(arr,i,j) 102 quick_sort33(arr,i,mid-1) 103 quick_sort33(arr,mid+1,j) 104 #4)非遞歸方式,使用棧,思路相似previous,只是把切分邊界保存在棧(用list實現)裏,\ 105 #當只剩一個元素時,跳出本次循環,進入下次循環,看下一個區間裏元素值是否多於1個,直到棧空 106 def quick_sort4(arr,i,j): 107 if j<=i: 108 return 109 stack=[] 110 stack.extend([i,j]) 111 while stack: 112 left=stack.pop(0) 113 right=stack.pop(0) 114 if right<=left: 115 continue 116 x=left-1 117 p=arr[right] 118 for y in range(left,right):#此處循環不包括最後一個元素,循環結束後,最後一個元素換到中間 119 if arr[y]<=p: 120 x+=1 121 arr[x],arr[y]=arr[y],arr[x] 122 arr[x+1],arr[right]=arr[right],arr[x+1] 123 stack.extend([left,x,x+2,right]) 124 125 126 if __name__=="__main__": 127 s=np.random.randint(1,30,20).tolist() 128 print(s) 129 #print(quick_sort24(s)) 130 quick_sort4(s,0,len(s)-1) 131 print(s)
相關文章
相關標籤/搜索