11import  random 
22
33
4- def  quickSelect (seq , k ):
5-     # 이 부분은 퀵 정렬과 같다. 
4+ def  quick_select_cache (seq , k ):
65    len_seq  =  len (seq )
76    if  len_seq  <  2 :
87        return  seq [0 ]
8+ 
99    # 피벗을 무작위로 선택할 수 있다. 
1010    # pivot = random.choice(seq) 
1111    ipivot  =  len_seq  //  2 
@@ -14,23 +14,54 @@ def quickSelect(seq, k):
1414    smallerList  =  [x  for  i , x  in  enumerate (seq ) if  x  <=  pivot  and  i  !=  ipivot ]
1515    largerList  =  [x  for  i , x  in  enumerate (seq ) if  x  >  pivot  and  i  !=  ipivot ]
1616
17-     # 이 부분에서 퀵 정렬과 다르다. 
18-     m  =  len (smallerList ) +  1 
17+     m  =  len (smallerList )
1918    if  k  ==  m :
2019        return  pivot 
2120    elif  k  <  m :
22-         return  quickSelect (smallerList , k )
21+         return  quick_select_cache (smallerList , k )
2322    else :
24-         return  quickSelect (largerList , k - m - 1 )
23+         return  quick_select_cache (largerList , k - m - 1 )
2524
2625
27- if  __name__  ==  "__main__" :
28-     seq  =  [10 , 60 , 100 , 50 , 60 , 75 , 31 , 50 , 30 , 20 , 120 , 170 , 200 ]
29-     # seq = [3, 7, 2, 1, 4, 6, 5, 10, 9, 11] 
26+ def  swap (seq , x , y ):
27+     seq [x ], seq [y ] =  seq [y ], seq [x ]
28+ 
29+ 
30+ def  quick_select (seq , k , left = None , right = None ):
31+     left  =  left  or  0 
32+     right  =  right  or  len (seq ) -  1 
33+     # ipivot = random.randint(left, right) 
34+     ipivot  =  len (seq ) //  2 
35+     pivot  =  seq [ipivot ]
36+ 
37+     # 피벗을 정렬 범위 밖으로 이동한다. 
38+     swap (seq , ipivot , right )
39+     swapIndex , i  =  left , left 
40+     while  i  <  right :
41+         if  pivot  <  seq [i ]:
42+             swap (seq , i , swapIndex )
43+             swapIndex  +=  1 
44+         i  +=  1 
3045
46+     # 피벗 위치를 확정한다. 
47+     swap (seq , right , swapIndex )
48+ 
49+     # 피벗 위치를 확인한다. 
50+     rank  =  len (seq ) -  swapIndex 
51+     if  k  ==  rank :
52+         return  seq [swapIndex ]
53+     elif  k  <  rank :
54+         return  quick_select (seq , k , swapIndex + 1 , right )
55+     else :
56+         return  quick_select (seq , k , left , swapIndex - 1 )
57+ 
58+ 
59+ if  __name__  ==  "__main__" :
60+     seq  =  [3 , 7 , 2 , 1 , 4 , 6 , 5 , 10 , 9 , 11 ]
3161    k  =  len (seq ) //  2 
3262    print (sorted (seq ))
33-     print (quickSelect (seq , k ))
63+     print (quick_select_cache (seq , k - 1 ))
64+     print (quick_select (seq , k ))
3465    # 중앙값(median) 출력을 위해서 넘파이를 사용함 
3566    import  numpy 
3667    print (numpy .median (seq ))
0 commit comments