#include <cstdio>
#include <cstdlib>
using namespace std;
void swap(int &a, int &b) {
int aux = a;
a = b;
b = aux;
}
void printArray(int* arr, int n) {
for (int i = 0; i < n; ++ i) {
printf("%d ", arr[i]);
}
printf("\n");
}
int lomutopartition(int* arr, int left, int right) {
// does three more swaps, on average than Hoare's partition scheme
int pivotIndex = left + rand() % (right - left + 1);
swap(arr[pivotIndex], arr[right]);
int begin = left;
for (int j = left; j < right; ++ j) {
if (arr[j] <= arr[right]) {
swap(arr[j], arr[begin]);
++ begin;
}
}
swap(arr[begin], arr[right]);
return begin;
}
int hoarepartition(int* arr, int left, int right) {
int pivotVal = arr[left + rand() % (right - left + 1)];
int i = left;
int j = right;
while (true) {
while (arr[i] < pivotVal) {
++ i;
}
while (arr[j] > pivotVal) {
-- j;
}
if (i >= j) {
return j;
}
swap(arr[i], arr[j]);
++ i;
-- j;
}
return 0;
}
void qsort(int* arr, int left, int right) {
if (right <= left) {
return;
}
//WIth HOARE partition scheme. the returned index is not the index of the pivot
int i = hoarepartition(arr, left, right);
qsort(arr, left, i);
qsort(arr, i + 1, right);
/* // WITH LOMUTO
int i = lomutopartition(arr, left, right);
qsort(arr, left, i - 1);
qsort(arr, i + 1, right);
*/
}
void merge(int *arr, int left, int mid, int right, int* result) {
int i = left;
int j = mid + 1;
for (int k = left; k <= right; ++ k) {
if (i <= mid && j <= right) {
if (arr[i] < arr[j]) {
result[k] = arr[i];
++ i;
} else {
result[k] = arr[j];
++ j;
}
} else if (i <= mid) {
result[k] = arr[i];
++ i;
} else {
result[k] = arr[j];
++ j;
}
}
}
void copyback(int* result, int left, int right, int *arr) {
for (int k = left; k <= right; ++ k) {
arr[k] = result[k];
}
}
void mergeSort(int* arr, int left, int right, int* result) {
if (left == right) {
return;
}
int mid = left + ((right - left) >> 1);
mergeSort(arr, left, mid, result);
mergeSort(arr, mid + 1, right, result);
merge(arr, left, mid, right, result);
copyback(result, left, right, arr);
}
void insertionSort(int* arr, int n) {
for (int i = 1; i < n; ++ i) {
int j = i;
while (j > 0 && arr[j - 1] > arr[j]) {
swap(arr[j], arr[j - 1]);
-- j;
}
}
}
int partitionKthOrder(int* arr, int left, int right) {
// pick random pivot
int pivotIndex = left + rand() % (right - left + 1);
swap(arr[pivotIndex], arr[right]);
int begin = left;
for (int i = left; i < right; ++ i) {
if (arr[i] <= arr[right]) {
swap(arr[begin], arr[i]);
++ begin;
}
}
return 0;
}
int kthOrderStatistic(int* arr, int left, int right, int k) {
int i = partitionKthOrder(arr, left, right);
return 0;
}
int main() {
freopen("algsort.in", "r", stdin);
freopen("algsort.out", "w", stdout);
int n;
scanf("%d", &n);
int* arr = new int[n];
int* finalMerge = new int[n];
for (int i = 0; i < n; ++ i) {
scanf("%d", &arr[i]);
}
qsort(arr, 0, n - 1);
//mergeSort(arr, 0, n - 1, finalMerge);
//insertionSort(arr, n);
printArray(arr, n);
delete[] arr;
return 0;
}