Python search for the k-th small element code sharing

Source: Internet
Author: User

Copy codeThe Code is as follows:
#-*-Coding: UTF-8 -*-

From random import randint
From math import ceil, floor

Def _ partition (A, l, r, I ):
"Uses A [I] as the primary element to divide the array A [l. r] so that:
A [l .. M-1] <= A [m] <A [m + 1. r]
"""
A [I], A [r] = A [r], A [I] # I is switched to the last r as the principal component
Principal = A [r] # Principal Component
M = l # index tag
For n in xrange (l, r): # l .. R-1
If A [n] <= then:
A [m], A [n] = A [n], A [m] # exchange
M + = 1 # Move back
A [m], A [r] = A [r], A [m] # principal component to m bit
Return m

Def _ rand (A, l, r ):
"Random division of Principal Components """
Return randint (l, r) # A [l. r] Random

Def _ select (A, l, r, k, effect_selector = _ rand ):
"Uses the fast rank to obtain the number of k smaller values in A [l. r], k in [l + 1, r + 1]:

Its tail recursion method, the pseudo code is as follows:
SELECT (A, l, r, k)
1 while true:
2 I branch? // Divide the principal component Position
3 m PARTITION (A, l, r, I) // array Division
4 n then m-l + 1 // A [l. m] Number of Elements
5 if k = n // check whether A [m] is A small k element.
6 then return A [m]
7 elseif k <n // left Partition
8 r = m-1
9 else // right Partition
10 k = k-n
11 l = m + 1

Args:
Effect_selector (Function): Specifies the principal component selection method. The default value is random.
"""
If not:
Return None
If l = r:
Return A [l]
While True:
I = effect_selector (A, l, r)
M = _ partition (A, l, r, I)
N = m-l + 1
If k = n:
Return A [m]
Elif k <n:
R = m-1
Else:
K = k-n
L = m + 1

Def rand_select (A, k ):
"Default random division of principal components, k in [1, len (A)]
E [T (n)] = O (n)
"""
Return _ select (A, 0, len (A)-1, k );


Def _ median (A, l, r ):
"Insert A [l. r] To sort (in situ) and select the position of the digits """
For j in xrange (l, r + 1 ):
K = A [j]
I = j
While I> l and A [I-1]> k:
A [I] = A [I-1]
I-= 1
A [I] = k
Return l + int (r-l) * 0.5) # lower median

Def _ medianOfMedians (A, l, r ):
"Median method:
1. Divided into floor (n/5) 5 tuples, and the rest (n % 5) form the last group.
2. Find the respective median of the ceil (n/5) groups. Insert and sort each group, and then select the median.
3. Repeat the preceding operation on the ceil (n/5) medians found in step 1 until there is only one median.
"""
If l = r:
Return l
N = r-l + 1 # Number of Elements
M = int (ceil (n/5.0) # Number of groups, each with 5 elements
For I in xrange (m ):
# Start and second bits of each group
Sub_l = l + I * 5
Sub_r = sub_l + 4
If sub_r> r:
Sub_r = r
# After each group of elements is inserted and sorted, select the median
Sub_m = _ median (A, sub_l, sub_r) # median Index
# Switch median to the first digit
J = l + I
A [j], A [sub_m] = A [sub_m], A [j]
Return _ medianOfMedians (A, l, l + m-1) # Median

Def bfprt_select (A, k ):
"Median method (BFPRT algorithm)
T (n) = O (n)
"""
Return _ select (A, 0, len (A)-1, k, _ medianOfMedians );


Def _ median3 (A, l, r ):
"Three-digit median method, take l, r, (l + r)/2 three-digit median """
C = (l + r)/2
Keys = [l, c, r]
I = _ median (keys, 0, 2)
Return keys [I]

Def median_select (A, k ):
"Three-digit median approach to Eliminate the Worst Case """
Return _ select (A, 0, len (A)-1, k, _ median3 );


If _ name _ = '_ main __':
Import random, time
From copy import copy

Print ('preparing data ...')
N = 1000000
Nums = range (n)
Random. shuffle (nums)
Print ('ready go! ')

Def timeit (fnc, * args, ** kargs ):
Print ('% s starts processing' % fnc. _ name __)
Begtime = time. clock ()
Retval = fnc (* args, ** kargs)
Endtime = time. clock ()
Print ('% s takes time: % F' % (fnc. _ name __, endtime-begtime ))
Return retval

Test_methods = [rand_select, bfprt_select, median_select]
K = random. randrange (n) + 1
Dashes = '---' * 10
For test in test_methods:
Print (dashes)
Nums_new = copy (nums)
Result = timeit (test, nums_new, k)
Print (the % dth smallest element: % d' % (k, result ))

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.