Kの多数を打つために、線形時間

トップKは2つのヒープに基づくアルゴリズムは、主に高速でソートに基づいており追求、自分の時間の複雑さです(\ O(nlogK))\イデオロギー分割統治、および間隔部門のクイックソートを用いて、我々は行うことができます\(O(n)を\)時間複雑。次のようなアルゴリズムのアイデアは、次のとおりです。

  • ステップ1、5いくつかのグループに独自のデータセット、グループとして最後に残った5つの未満の余分な、グループの総数\(G = \ \ rceil \ {N-lceil / 5})
  • ステップ2及び図3に示すように、挿入ソートアルゴリズムを使用して、各グループに5つの要素の並べ替えに、データの各グループのために、次いでメディアン順次前方に、最終的な\(A [0、G- 1] \ 保存されてはいる(G \)\グループそれぞれの中央値;
  • 再帰呼び出しを取得するステップ4、\(A [0、G- 1] \) 、要素である中央値の\(A [G / 2] \) 直接得られるかどうかわかりません。
  • 右ステップ5、中央値のデータ区間を分割する上記ステップを得るために、中央値が少ない左よりは、上に位置する中央値、中央値よりも大きい\(K \)位置。
  • ステップ6、私たちが探している場合は、単に最初のです\(K \)タルスス、そしてちょうど中央値はまた、所望されます。
  • ステップ7は、場合\(iは<K \)まず探している\(I \)間隔で多数\(A [0 ,. 1-K] \) 再帰的な取得の左半分I(\ \ )大量。
  • ステップ8、もし(I> K \)\我々が最初に探している\(I \)間隔で多数の\(A [K + 1:-1] \) 再帰的な取得の右半分\(IK \)が多数。
def insert_sort(data, left, right):

    # 对列表 data[left, right] 进行插入排序

    for i in range(left+1, right+1):
        num = data[i]
        for j in range(i, left, -1):
            if num < data[j-1]:
                data[j] = data[j-1]
            else:
                break
        data[j] = num


def swap(data, i, j):

    # 交换列表 data 位于 i,j 的元素

    temp = data[i]
    data[i] = data[j]
    data[j] = temp


def partition(data, x):

    # 按照列表 data 第 x 个元素分区

    n = len(data)
    i = 0
    pivot = data[x]
    swap(data, x, n-1)
    for j in range(0, n):
        if data[j] < pivot:
            swap(data, i, j)
            i += 1

    data[j] = data[i]
    data[i] = pivot

    return i


def select_ith_min(data, i):

    # 选取列表 data 中第 i 小的元素

    n = len(data)

    # 不要忘了递归终止
    if n == 1:
        return data[0]

    if n % 5 == 0:
        group = n // 5
    else:
        group = n // 5 + 1
    for j in range(0, group):
        start = j * 5
        end = start + 4
        if end > n - 1:
            end = n - 1
        insert_sort(data, start, end)
        mid = (end - start + 1) // 2 + start
        swap(data, j, mid)

    pivot = data[group // 2]
    k = partition(data, group // 2)

    if k == i-1:
        return pivot
    elif k > i-1:
        return select_ith_max(data[0:k], i)
    else:
        return select_ith_max(data[k:], i-k)


a = [i for i in range(100, 0, -1)]
print(a)
for i in range(1, 101):
    num = select_ith_max(a, i)
    print(num)

よりエキサイティングな、してください注意を払うために「seniusen」!

おすすめ

転載: www.cnblogs.com/seniusen/p/11979903.html