Jump to content

сорт американского флага

Сортировка по американскому флагу — это эффективный на месте вариант поразрядной сортировки , который распределяет элементы по сегментам. Алгоритмы несравнительной сортировки, такие как поразрядная сортировка и сортировка по американскому флагу, обычно используются для сортировки больших объектов, таких как строки, для которых сравнение не является операцией за единицу времени. [1] Сортировка по американскому флагу перебирает биты объектов, рассматривая одновременно несколько битов каждого объекта. Для каждого набора битов сортировка по американскому флагу делает два прохода по массиву объектов: сначала для подсчета количества объектов, которые попадут в каждую корзину, а затем для помещения каждого объекта в свою корзину. Это особенно хорошо работает при побайтной сортировке с использованием 256 сегментов. С некоторыми оптимизациями она работает в два раза быстрее, чем быстрая сортировка для больших наборов строк . [1]

Название «Сортировка американского флага» происходит по аналогии с проблемой голландского национального флага на последнем этапе: эффективно разделить массив на множество «полос».

Алгоритм

[ редактировать ]

Алгоритмы сортировки обычно сортируют список объектов в соответствии с некоторой схемой упорядочения. В отличие от алгоритмов сортировки на основе сравнения , таких как быстрая сортировка , сортировка по американскому флагу основана на прямом сравнении байтов (числовом представлении) базовых объектов. Алгоритмы сортировки на месте, включая сортировку по американскому флагу, выполняются без выделения значительного объема памяти сверх того, который используется исходным массивом. Это значительное преимущество как в плане экономии памяти, так и во времени при копировании массива.

Сортировка по американскому флагу работает путем последовательного разделения списка объектов на сегменты на основе первой цифры их представления по основанию N (используемая база называется системой счисления ). Когда N равно 3, каждый объект можно переместить в правильную корзину с помощью алгоритма национального флага Нидерландов . Однако когда N больше, объекты не могут быть немедленно переставлены на места, поскольку неизвестно, где должен начинаться и заканчиваться каждый сегмент. Сортировка по американскому флагу позволяет обойти эту проблему, выполняя два прохода по массиву. Первый проход подсчитывает количество объектов, принадлежащих каждому из N сегментов. Начало каждого сегмента затем вычисляется как сумма размеров предыдущих сегментов. Второй проход помещает каждый объект в правильную корзину.

Сортировка по американскому флагу наиболее эффективна при системе счисления, равной степени 2, поскольку можно использовать операции сдвига битов вместо дорогостоящего возведения в степень для вычисления значения каждой цифры . При сортировке строк с использованием 8- или 7-битных кодировок, таких как ASCII , обычно используется система счисления 256 или 128, что соответствует посимвольной сортировке. [1]

Вопросы производительности

[ редактировать ]

Стоит отметить, что для текста на чистом английском алфавите гистограмма счетчиков всегда разрежена. В зависимости от оборудования, возможно, стоит очистить счетчики при заполнении корзины (как в исходной статье); или, возможно, стоит поддерживать максимальный и минимальный активный сегмент или более сложную структуру данных, подходящую для разреженных массивов. Также важно использовать более простой метод сортировки для очень маленьких наборов данных, за исключением патологических случаев, когда ключи могут иметь очень длинные префиксы.

Самое главное, что этот алгоритм следует случайной перестановке и поэтому особенно недружелюбен к кэшу для больших наборов данных. [2] [ источник, созданный пользователем ] Это подходящий алгоритм в сочетании с k алгоритмом слияния -way . [ нужна ссылка ] (Оригинальная статья была написана до того, как кэш-память стала широко использоваться.)

Псевдокод

[ редактировать ]
american_flag_sort(Array, Radix)
    for each digit D:
        # first pass: compute counts
        Counts <- zeros(Radix)
        for object X in Array:
            Counts[digit D of object X in base Radix] += 1
        # compute bucket offsets
        Offsets <- [ sum(Counts[0..i]) for i in 1..Radix]
        # swap objects into place
        for object X in Array:
            swap X to the bucket starting at Offsets[digit D of X in base Radix]
        for each Bucket:
            american_flag_sort(Bucket, Radix)

Пример реализации на Python

[ редактировать ]

Этот пример, написанный на языке программирования Python, будет выполнять сортировку по американскому флагу для любого основания счисления, равного 2 или больше. Простота изложения предпочтительнее умного программирования, поэтому вместо методов сдвига битов используется функция журнала.

from math import floor, log
from copy import copy

def get_radix_val(x, digit, radix):
    return int(floor(x / radix**digit)) % radix

def compute_offsets(a_list, start, end, digit, radix):
    counts = [0 for _ in range(radix)]
    for i in range(start, end):
        val = get_radix_val(a_list[i], digit, radix)
        counts[val] += 1
    offset = start
    offsets = [start]
    for i in range(radix):
        offset += counts[i]
        offsets.append(offset)
    return offsets

def swap(a_list, offsets, start, end, digit, radix):
    next_free = copy(offsets)
    cur_block = 0
    while cur_block < radix:
        i = next_free[cur_block]
        if i >= offsets[cur_block+1]:
            cur_block += 1
            continue
        radix_val = get_radix_val(a_list[i], digit, radix)
        if radix_val != cur_block:
            swap_to = next_free[radix_val]
            a_list[i], a_list[swap_to] = a_list[swap_to], a_list[i]
        next_free[radix_val] += 1

def american_flag_sort_helper(a_list, start, end, digit, radix):
    offsets = compute_offsets(a_list, start, end, digit, radix)
    swap(a_list, offsets, start, end, digit, radix)
    if digit == 0:
        return
    for i in range(len(offsets)-1):
        american_flag_sort_helper(a_list, offsets[i], offsets[i+1], digit-1, radix)

def american_flag_sort(a_list, radix):
    for x in a_list:
        assert type(x) == int
    max_val = max(a_list)
    max_digit = int(floor(log(max_val, radix)))
    american_flag_sort_helper(a_list, 0, len(a_list), max_digit, radix)

См. также

[ редактировать ]
  1. Перейти обратно: Перейти обратно: а б с Макилрой, Питер М.; Бостик, Кейт; Макилрой, М. Дуглас (1993). «Инженерная поразрядная сортировка» (PDF) . Вычислительные системы . 6 (1): 5–27.
  2. ^ «Алгоритм — поразрядная сортировка на месте» . Переполнение стека . Проверено 18 октября 2020 г.
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: a354e8549c1bf416f83b037e3b1ef59d__1714680960
URL1:https://arc.ask3.ru/arc/aa/a3/9d/a354e8549c1bf416f83b037e3b1ef59d.html
Заголовок, (Title) документа по адресу, URL1:
American flag sort - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)