Дано два відсортовані масиви a , b типу T з розмірами n та m . Я шукаю алгоритм, який об'єднує два масиви в новий масив (максимального розміру n + m).
Якщо у вас дешева операція порівняння, це досить просто. Просто візьміть з масиву найнижчий перший елемент до повного проходження одного або обох масивів, а потім додайте решту елементів. Щось подібне /programming/5958169/how-to-merge-two-sorted-arrays-into-a-sorted-array
Однак ситуація змінюється при порівнянні двох елементів набагато дорожче, ніж копіювання елемента з вихідного масиву в цільовий масив . Наприклад, у вас може бути масив великих чисел із довільною точністю чи рядками, де порівняння може бути досить дорогим. Просто припустимо, що створення масивів та копіювання елементів є безкоштовним, і єдине, що коштує, це порівняння елементів.
У цьому випадку потрібно об'єднати два масиви з мінімальною кількістю порівнянь елементів . Ось кілька прикладів, коли ви повинні бути в змозі зробити набагато краще, ніж простий алгоритм злиття:
a = [1,2,3,4, ... 1000]
b = [1001,1002,1003,1004, ... 2000]
Або
a = [1,2,3,4, ... 1000]
b = [0,100,200, ... 1000]
Є деякі випадки, коли простий алгоритм злиття буде оптимальним, наприклад
a = [1,3,5,7,9,....,999]
b = [2,4,6,8,10,....,1000]
Тож алгоритм повинен ідеально деградувати і виконувати максимум n + m-1 порівнянь у випадку, якщо масиви переплетені, або принаймні не будуть значно гіршими.
Одне, що має бути досить добре для списків з великою різницею розмірів, - це використовувати двійковий пошук для вставки елементів меншого масиву у більший масив. Але це не виграшно виграє, якщо обидва списки однакового розміру та переплетені.
Єдине, що доступне для елементів - це (загальна) функція замовлення, тому будь-яка схема, яка робить порівняння дешевшими, неможлива.
Будь-які ідеї?
Я придумав цей шматочок у Скалі . Я вважаю, що це оптимально щодо кількості порівнянь, але це не в силах довести це. Принаймні, це набагато простіше, ніж речі, які я знайшов у літературі.
А з початкової публікації я написав допис у блозі про те, як це працює.