Heim Backend-Entwicklung Python-Tutorial python查找第k小元素代码分享

python查找第k小元素代码分享

Jun 16, 2016 am 08:45 AM
python

复制代码 代码如下:

# -*- coding: utf-8 -*-

from random import randint
from math import ceil, floor

def _partition(A, l, r, i):
    """以A[i]为主元划分数组A[l..r],使得:
    A[l..m-1]     """
    A[i], A[r] = A[r], A[i] # i交换到末位r,作为主元
    pivot = A[r] # 主元
    m = l # 索引标记
    for n in xrange(l, r): # l..r-1
        if A[n]             A[m], A[n] = A[n], A[m] # 交换
            m += 1 # 后移
    A[m], A[r] = A[r], A[m] # 主元到m位
    return m

def _rand(A, l, r):
    """随机划分主元"""
    return randint(l, r) # A[l..r]随机取一个

def _select(A, l, r, k, pivot_selector = _rand):
    """利用快排,得A[l..r]中第k小的数,k in [l+1,r+1]:

    其尾递归方式,伪码如下:
    SELECT(A, l, r, k)
    1  while true:
    2    i ← ? // 划分主元位置
    3    m ← PARTITION(A, l, r, i) // 数组划分
    4    n ← m - l + 1 // A[l..m]元素个数
    5    if k = n // 检查A[m]是否是第k小的元素
    6      then return A[m]
    7    elseif k     8      r = m - 1
    9    else // 右划分区
    10     k = k - n
    11     l = m + 1

    Args:
        pivot_selector(Function): 主元选取方法,默认随机方式
    """
    if not A:
        return None
    if l == r:
        return A[l]
    while True:
        i = pivot_selector(A, l, r)
        m = _partition(A, l, r, i)
        n = m - l + 1
        if k == n:
            return A[m]
        elif k             r = m - 1
        else:
            k = k - n
            l = m + 1

def rand_select(A, k):
    """默认随机划分主元方式,k in [1, len(A)]
    E[T(n)] = O(n)
    """
    return _select(A, 0, len(A) - 1, k);


def _median(A, l, r):
    """对A[l..r]插入排序(原地)后选取其中位数位置"""
    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) # 下中位数

def _medianOfMedians(A, l, r):
    """中位数的中位数方式:
    1. 划分为floor(n/5)个5元组,剩下(n%5)组成最后一组。
    2. 找出ceil(n/5)个组各自的中位数。先对每组插入排序,再从中选出中位数。
    3. 对第2步中找出的ceil(n/5)个中位数重复上述操作,直到仅有一个中位数。
    """
    if l == r:
        return l
    n = r - l + 1 # 元素个数
    m = int(ceil(n / 5.0)) # 划分组数,每组5个元素
    for i in xrange(m):
        # 每组起始位和结束位
        sub_l = l + i * 5
        sub_r = sub_l + 4
        if sub_r > r:
            sub_r = r
        # 对每组元素插入排序后,选取中位数
        sub_m = _median(A, sub_l, sub_r) # 中位数索引
        # 交换中位数到前几位
        j = l + i
        A[j], A[sub_m] = A[sub_m], A[j]
    return _medianOfMedians(A, l, l + m - 1) # 中位数的中位数

def bfprt_select(A, k):
    """中位数的中位数方式(BFPRT算法)
    T(n) = O(n)
    """
    return _select(A, 0, len(A) - 1, k, _medianOfMedians);


def _median3(A, l, r):
    """三数中位数方式,取l,r,(l+r)/2三数中位数"""
    c = (l + r) / 2
    keys = [l, c, r]
    i = _median(keys, 0, 2)
    return keys[i]

def median_select(A, k):
    """三数中位数方式,以消除最坏情况"""
    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))

Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
2 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌
Repo: Wie man Teamkollegen wiederbelebt
1 Monate vor By 尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Abenteuer: Wie man riesige Samen bekommt
4 Wochen vor By 尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

Notepad++7.3.1

Notepad++7.3.1

Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version

SublimeText3 chinesische Version

Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1

Senden Sie Studio 13.0.1

Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6

Dreamweaver CS6

Visuelle Webentwicklungstools

SublimeText3 Mac-Version

SublimeText3 Mac-Version

Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

Kann der Python -Dolmetscher im Linux -System gelöscht werden? Kann der Python -Dolmetscher im Linux -System gelöscht werden? Apr 02, 2025 am 07:00 AM

In Bezug auf das Problem der Entfernung des Python -Dolmetschers, das mit Linux -Systemen ausgestattet ist, werden viele Linux -Verteilungen den Python -Dolmetscher bei der Installation vorinstallieren, und verwendet den Paketmanager nicht ...

Wie löst ich das Problem der Erkennung von kundenspezifischen Dekoratoren in Python? Wie löst ich das Problem der Erkennung von kundenspezifischen Dekoratoren in Python? Apr 02, 2025 am 06:42 AM

Lösung für die Erkennung von Pylanztypen bei der Verwendung des benutzerdefinierten Dekorators in der Python -Programmierung ist Decorator ein leistungsstarkes Werkzeug, mit dem Zeilen hinzugefügt werden können ...

Wie löste ich Berechtigungsprobleme bei der Verwendung von Python -Verssionsbefehl im Linux Terminal? Wie löste ich Berechtigungsprobleme bei der Verwendung von Python -Verssionsbefehl im Linux Terminal? Apr 02, 2025 am 06:36 AM

Verwenden Sie Python im Linux -Terminal ...

Python 3.6 Laden Sie Giftedatei Fehler ModulenotFoundError: Was soll ich tun, wenn ich die Gurkendatei '__builtin__' lade? Python 3.6 Laden Sie Giftedatei Fehler ModulenotFoundError: Was soll ich tun, wenn ich die Gurkendatei '__builtin__' lade? Apr 02, 2025 am 06:27 AM

Laden Sie die Gurkendatei in Python 3.6 Umgebungsfehler: ModulenotFoundError: Nomodulenamed ...

Teilen Fastapi und AIOHTTP dieselbe globale Ereignisschleife? Teilen Fastapi und AIOHTTP dieselbe globale Ereignisschleife? Apr 02, 2025 am 06:12 AM

Kompatibilitätsprobleme zwischen asynchronen Python -Bibliotheken in Python, asynchrones Programmieren ist zum Prozess der hohen Parallelität und der I/O geworden ...

Was soll ich tun, wenn das Modul '__builtin__' beim Laden der Gurkendatei in Python 3.6 nicht gefunden wird? Was soll ich tun, wenn das Modul '__builtin__' beim Laden der Gurkendatei in Python 3.6 nicht gefunden wird? Apr 02, 2025 am 07:12 AM

Laden Sie Gurkendateien in Python 3.6 Umgebungsbericht Fehler: ModulenotFoundError: Nomodulennamen ...

Wie kann ich sicherstellen, dass der Kinderprozess auch endet, nachdem er den übergeordneten Prozess über Signal in Python getötet hat? Wie kann ich sicherstellen, dass der Kinderprozess auch endet, nachdem er den übergeordneten Prozess über Signal in Python getötet hat? Apr 02, 2025 am 06:39 AM

Das Problem und die Lösung des Kinderprozesses werden weiterhin ausgeführt, wenn Signale zum Töten des übergeordneten Prozesses verwendet werden. In der Python -Programmierung, nachdem er den übergeordneten Prozess durch Signale getötet hatte, ist der Kinderprozess immer noch ...

See all articles