Merge Sort

**Merge sort — (Birlashtirib saralash)** algoritmi asosiy beshta saralash algoritmlari (Bubble sort, Quick sort va boshqalar) dan biri boʻlib, chiziqli saralash algoritmlaridan farqli ravishda „boʻlib tashla va hukmronlik qil“ tipidagi algoritm hisoblanadi. Bu turdagi algoritmlar katta hajmdagi masalalarni nisbatan kichik boʻlgan va oson yechiladigan qismlarga ajratgan holda bajaradi. Bunday algoritmlar masalalarni yechishda vaqtdan yutish imkonini beradi.

## Merge sort algoritmi
* Merge Sort funksiyasiga massiv va uning boshlangʻich (eng chapdagi element) va oxirgi nuqtalari (eng oʻngdagi element) beriladi.
* Massivning oʻrtasi hisoblanadi: oʻrtasi = (chap + oʻng)/2. Bu narsa uni teng ikkiga boʻlish uchun kerak boʻladi.
* Merge sortni rekursiv holda birinchi va ikkinchi qismlar uchun chaqiriladi.
* 2- va 3-qismlarda hosil boʻlgan massivlar birlashtirib chiqiladi.
Algoritm ishlash tezligi O(n*log(n)) boʻlib tezligi O(n2) boʻlgan oddiy Bubble sort, Insertion sort, Selection sortlardan ancha tez ishlaydi. Taqqoslash asosida ishlaydigan algortmlarning eng tez ishlash holati O(n*log(n)) boʻlishi isbotlangan.

## Dasturi

```
#include <iostream>
using namespace std;

void merge(int array[], int const left, int const mid, int const right)
{
    auto const subArrayOne = mid - left + 1;
    auto const subArrayTwo = right - mid;

    auto *leftArray = new int[subArrayOne],
         *rightArray = new int[subArrayTwo];

    for (auto i = 0; i < subArrayOne; i++)
        leftArray[i] = array[left + i];
    for (auto j = 0; j < subArrayTwo; j++)
        rightArray[j] = array[mid + 1 + j];
 
    auto indexOfSubArrayOne = 0,
        indexOfSubArrayTwo = 0;
    int indexOfMergedArray = left;
    while (indexOfSubArrayOne < subArrayOne && indexOfSubArrayTwo < subArrayTwo) {
        if (leftArray[indexOfSubArrayOne] <= rightArray[indexOfSubArrayTwo]) {
            array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
            indexOfSubArrayOne++;
        }
        else {
            array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo];
            indexOfSubArrayTwo++;
        }
        indexOfMergedArray++;
    }
    while (indexOfSubArrayOne < subArrayOne) {
        array[indexOfMergedArray] = leftArray[indexOfSubArrayOne];
        indexOfSubArrayOne++;
        indexOfMergedArray++;
    }
    while (indexOfSubArrayTwo < subArrayTwo) {
        array[indexOfMergedArray] = rightArray[indexOfSubArrayTwo];
        indexOfSubArrayTwo++;
        indexOfMergedArray++;
    }
}
void mergeSort(int array[], int const begin, int const end)
{
    if (begin >= end)
        return; // Returns recursively
    auto mid = begin + (end - begin) / 2;
    mergeSort(array, begin, mid);
    mergeSort(array, mid + 1, end);
    merge(array, begin, mid, end);
}
void printArray(int A[], int size)
{
    for (auto i = 0; i < size; i++)
        cout << A[i] << " ";
}
int main()
{
    int arr[] = { 12, 11, 13, 5, 6, 7 };
    auto arr_size = sizeof(arr) / sizeof(arr[0]);
    cout << "Given array is \n";
    printArray(arr, arr_size);
    mergeSort(arr, 0, arr_size - 1);
    cout << "\nSorted array is \n";
    printArray(arr, arr_size);
    return 0;
}
```
.

## Kamchiligi
* Kichikroq vazifalar uchun boshqa tartiblash algoritmlariga nisbatan sekinroq.
* Merge sort algoritmi vaqtinchalik massiv uchun 0(n) qoʻshimcha xotira maydonini talab qiladi.
* Agar massiv tartiblangan boʻlsa ham, u butun jarayondan oʻtadi.
## Manbalar