﻿#include <iostream>
using namespace std;

/*
    Összefésülő rendezés (mergesort)

    Összefésülés
        - két rendezett sorozatból gyártunk
        egy harmadik rendezett sorozatot,
        amely a sorozatok
        minden elemét tartalmazza

        Pl.
        bemenet:
            1 3 4 8 9        1 2 2 5 7 100
            ^                ^

        kimenet (szintén rendezett):
            1 1 2 2 3 4 5 7 8 9 100
*/
void osszefesules(
    int a[], int na,
    int b[], int nb,
    int c[])
{
    int ia = 1, ib = 1;
    int ic = 0;

    while (ia <= na && ib <= nb) {
        if (a[ia] <= b[ib]) {
            ic++;
            c[ic] = a[ia];
            ia++;
        }
        else {
            ic++;
            c[ic] = b[ib];
            ib++;
        }
    }

    while (ia <= na) {
        ic++;
        c[ic] = a[ia];
        ia++;
    }

    while (ib <= nb) {
        ic++;
        c[ic] = b[ib];
        ib++;
    }
}

/*
    Összefésülő rendezés

    Minden lépésben a rendezendő darabot
    két részre osztjuk, ezeket külön-
    külön rendezzük, majd a két rendezett
    darabot összefésüljük.

    Pl.
        1 3 8 9 4     2 2 5 1 100 7
        rek. hívás    rek. hívás
        1 3 4 8 9     1 2 2 5 7 100
                  összefésülés
        1 1 2 2 3 4 5 7 8 9 100
*/

void merge_helyben(
    int t[], int bal, int kozep, int jobb)
{
    int c[1001];
    int ic = 0;

    int ia = bal;
    int ib = kozep+1;

    while (ia <= kozep && ib <= jobb) {
        if (t[ia] <= t[ib]) {
            ++ic;
            c[ic] = t[ia];
            ia++;
        }
        else {
            ++ic;
            c[ic] = t[ib];
            ib++;
        }
    }

    while (ia <= kozep) {
        ++ic;
        c[ic] = t[ia];
        ia++;
    }

    while (ib <= jobb) {
        ++ic;
        c[ic] = t[ib];
        ib++;
    }

    // másolás c-ből t-be
    for (int i = 1; i <= ic; i++)
        t[bal+i-1] = c[i];
}


void mergesort(int t[], int bal, int jobb)
{
    if (bal >= jobb)
        return;

    int kozep = (bal + jobb) / 2;

    mergesort(t, bal, kozep);
    mergesort(t, kozep+1, jobb);

    merge_helyben(t, bal, kozep, jobb);
}

/* HF:
    1. Kövessük nyomon a mergesort működését
       debuggerrel egy 10 elemű sorozatra.

    2. Írjunk módosítot mergesort-ot, ami
       csökkenő sorrendbe rendez.
*/

int main()
{
    /* 
    // Összefésülés tesztelése
    // beolvasás
    cout << "na = ";
    int na, a[101];
    cin >> na;

    cout << "a[] elemei: ";
    for (int i = 1; i <= na; ++i)
        cin >> a[i];

    cout << "nb = ";
    int nb, b[101];
    cin >> nb;

    cout << "b[] elemei: ";
    for (int i = 1; i <= nb; ++i)
        cin >> b[i];

    // összefésülés
    int c[201];
    osszefesules(a, na, b, nb, c);
    int nc = na + nb;

    // kiírás
    for (int i = 1; i <= nc; ++i)
        cout << c[i] << ' ';
    cout << endl;
    */

    int n;
    cin >> n;

    int t[1001];
    for (int i = 1; i <= n; ++i)
        cin >> t[i];

    mergesort(t, 1, n);

    for (int i = 1; i <= n; ++i)
        cout << t[i] << ' ';
    cout << endl;
    return 0;
}
