From mergesort_recursion import mergesort import random Def partion (A, M, M_index): #对a进行排序, so that elements smaller than m are placed in front of M, and the elements larger than m are placed behind M.
Input: M_index (M in A's index) #返回m前面, the number of individual elements after m, and the index #将m与数组第一个元素交换位置 of M in the new array, and then you can sort all the elements with m as an intermediate element #分到左右两边 TMP = a[0] A[0] = m A[m_index] = tmp i = 0 j = Len (a)-1 control_m = a[0] While I < J:while i< J and A[j] >= contro L_m:j-= 1 A[i] = A[j] While I < J and A[i] <= control_m:i = 1 A[j] = A[i] #此时i = j, A[i] should be the final control Keyword location A[i] = control_m print ("M:{},after partion, a:{}". Format (M, a)) return I, Len (a)-i-1, I def bfprt (A, k): #得 To a K-large element If Len (a) < 5: #元素数目不足5个时, sorted after the number of index k-1, that is, the K-large element #由于只有在元素数目很小时才使用排序, so the time complexity is very small, can be regarded as constant time complexity mergesort
(a,0, Len (a)-1) return a[k-1] Total_num = Len (a) splits = TOTAL_NUM//5 #一共分成这么多组 #获取每一个分组的中位数 Split_medians = [] For I in range (splits): cur = mergesort (a[i*5: (i+1) *5],0, 4) mid = Cur[2] Split_medians.append (mid) #递归调用bfprt算法 , and to find the elements in the middle of these median splits//2 large,Which is the median m = bfprt (Split_medians, SPLITS//2) #求出m在a中的index m_index = [I for I in range (Total_num) if a[i] = = M][0] #根据m对a进行划分, linear complexity #num1, num2: The number of elements less than m, the number of elements greater than M num1, num2, M_index = Partion (A, M, m_index) if k = = Num1+1:return M elif k <= num1: #说明在s1集合中 return Bfprt (A[:m_index], k) Else:return Bfprt (a[m_index+1:], k-1-m_index) A = [ 5, 3, 1, 8, 2,10, 11,13, 0, 6, 4, 7, 9,] Random.shuffle (a) k = 3 print (BFPRT (a,7))
BFPRT Algorithm general idea:
1. Divide all n data into N/5 (rounded down) groups with 5 elements in each group, the median number of each group (time complexity is *5log5 * N/5, i.e. O (n)) is calculated by merging/fast sorting, and the recursive call BFPRT algorithm is used to find the median number of N/5 median (T (N/5)), That is, the N/10 large element, recorded as M, finds the position of M in the original array index (O (n)).
2. Place the original array with M as the dividing point, place the num2 element greater than M on the right side of M, the NUM1 element less than or equal to M on the left of M, where the new position of M is index_new
Note here that you should interchange m with the first element position before finding the appropriate position for m ...
3. Compare K with Num1, if k=num1+1, then the demarcation point M is the K-large element, if K<=NUM1, the K-large elements in m left, then go to M left to look for, otherwise on the right of M, should go to M right. This translates the original question into a smaller problem.