összefésülő rendezés

Kiejtés

  • IPA: [ ˈøsːɛfeːʃyløːrɛndɛzeːʃ]

Főnév

összefésülő rendezés

  1. (matematika, algoritmusok) Az összefésülő rendezés egy oszd meg és uralkodj alapú rendezési algoritmus. Az algoritmus a bemeneti tömböt kisebb részekre bontja, majd ezeket a részeket rekurzívan rendezi, és végül egy lépésben összefésüli a rendezett részeket.



Működése

  1. Oszd:
    • Bontsuk a tömböt két egyenlő méretű (vagy majdnem egyenlő) részre.
  2. Rendezd:
    • Rekurzívan rendezzük a bal és a jobb részt külön-külön.
  3. Fésüld össze:
    • A két rendezett részhalmazból egy rendezett tömböt készítünk az összefésülés (merge) lépésével.



Tulajdonságok

  • Időkomplexitás: Mindig (O(n n)), mivel a tömb méretét minden lépésben megfelezzük ((n)), és minden lépésben végig kell haladni az összes elemen ((n)).
  • Térkomplexitás: (O(n)), mert az összeolvasztás során ideiglenes tárolót kell használni.
  • Stabilitás: Stabil, mivel az azonos értékű elemek sorrendje nem változik meg.
  • Alkalmazás:
    • Nagy adathalmazokon hatékony, különösen akkor, ha az adatok nem helyben vannak (pl. fájlok).



Pszeudokód

MergeSort(A):
    ha A mérete ≤ 1:
        térj vissza A
    osszuk A-t két részre: bal és jobb
    bal = MergeSort(bal)
    jobb = MergeSort(jobb)
    térj vissza Merge(bal, jobb)

Merge(bal, jobb):
    hozz létre egy üres listát, merge
    amíg bal és jobb nem üres:
        ha bal[0] ≤ jobb[0]:
            merge-hez adjuk hozzá bal[0]-t
            távolítsuk el bal[0]-t
        különben:
            merge-hez adjuk hozzá jobb[0]-t
            távolítsuk el jobb[0]-t
    adjuk hozzá merge-hez a maradék elemeket bal-ból és jobb-ból
    térj vissza merge

Python implementáció

def merge_sort(arr):
    if len(arr) <= 1:
        return arr

    # Tömb kettéosztása
    mid = len(arr) // 2
    left = merge_sort(arr[:mid])
    right = merge_sort(arr[mid:])

    # Két részhalmaz összefésülése
    return merge(left, right)

def merge(left, right):
    merged = []
    i = j = 0

    # Összefésülés
    while i < len(left) and j < len(right):
        if left[i] <= right[j]:
            merged.append(left[i])
            i += 1
        else:
            merged.append(right[j])
            j += 1

    # Maradék elemek hozzáadása
    merged.extend(left[i:])
    merged.extend(right[j:])
    return merged

# Példa
data = [38, 27, 43, 3, 9, 82, 10]
sorted_data = merge_sort(data)
print("Rendezett tömb:", sorted_data)
# Kimenet: Rendezett tömb: [3, 9, 10, 27, 38, 43, 82]

C++ implementáció

#include <iostream>
#include <vector>

using namespace std;

void merge(vector<int>& arr, int left, int mid, int right) {
    int n1 = mid - left + 1;
    int n2 = right - mid;

    vector<int> L(n1), R(n2);

    for (int i = 0; i < n1; ++i) {
        L[i] = arr[left + i];
    }
    for (int j = 0; j < n2; ++j) {
        R[j] = arr[mid + 1 + j];
    }

    int i = 0, j = 0, k = left;

    while (i < n1 && j < n2) {
        if (L[i] <= R[j]) {
            arr[k] = L[i];
            ++i;
        } else {
            arr[k] = R[j];
            ++j;
        }
        ++k;
    }

    while (i < n1) {
        arr[k] = L[i];
        ++i;
        ++k;
    }

    while (j < n2) {
        arr[k] = R[j];
        ++j;
        ++k;
    }
}

void merge_sort(vector<int>& arr, int left, int right) {
    if (left < right) {
        int mid = left + (right - left) / 2;

        merge_sort(arr, left, mid);
        merge_sort(arr, mid + 1, right);

        merge(arr, left, mid, right);
    }
}

int main() {
    vector<int> data = {38, 27, 43, 3, 9, 82, 10};

    merge_sort(data, 0, data.size() - 1);

    cout << "Rendezett tömb: ";
    for (int num : data) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

Kimenet:

Rendezett tömb: 3 9 10 27 38 43 82

Optimalizációk

  1. Kisebb részek rendezése:
    • Kis méretű tömbökön érdemes beszúrásos rendezésre váltani, mivel az hatékonyabb.
  2. In-place Merge Sort:
    • Helyben történő rendezést alkalmazhatunk, hogy csökkentsük a térkomplexitást (O(n))-ről (O(n))-re.



Összegzés

Az összefésülő rendezés rendkívül hatékony algoritmus nagy adathalmazok rendezésére, különösen akkor, ha az elemek külső memóriában találhatók (pl. fájlok). Stabilitása és determinisztikus (O(n n)) időkomplexitása miatt számos alkalmazásban népszerű. A memóriaigénye miatt azonban helyspecifikus optimalizációk szükségesek lehetnek bizonyos esetekben.


Fordítások