import java.util.Scanner;
public class Main {
private static final int INSERTION_THRESHOLD = 10;
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] array = new int[n];
for (int i = 0; i < n; i++) {
array[i] = sc.nextInt();
}
quickSort(array, 0, n - 1);
for (int num : array) {
System.out.print(num + " ");
}
sc.close();
}
public static void quickSort(int[] q, int l, int r) {
// 使用尾递归优化的迭代写法
while (l < r) {
if (r - l + 1 <= INSERTION_THRESHOLD) {
insertionSort(q, l, r);
break;
} else {
int[] p = partition(q, l, r);
// 先处理较小的分区以减少栈深度
if (p[0] - l < r - p[1]) {
quickSort(q, l, p[0] - 1);
l = p[1] + 1;
} else {
quickSort(q, p[1] + 1, r);
r = p[0] - 1;
}
}
}
}
private static int[] partition(int[] q, int l, int r) {
// 三数取中法选择基准
int mid = l + (r - l) / 2;
int pivot = medianOfThree(q[l], q[mid], q[r]);
int i = l - 1, j = r + 1;
while (i < j) {
do { i++; } while (q[i] < pivot);
do { j--; } while (q[j] > pivot);
if (i < j) {
swap(q, i, j);
}
}
return new int[]{i, j};
}
private static int medianOfThree(int a, int b, int c) {
if ((a > b) ^ (a > c))
return a;
else if ((b > a) ^ (b > c))
return b;
else
return c;
}
private static void insertionSort(int[] q, int l, int r) {
for (int i = l + 1; i <= r; i++) {
int temp = q[i];
int j = i;
while (j > l && q[j - 1] > temp) {
q[j] = q[j - 1];
j--;
}
q[j] = temp;
}
}
private static void swap(int[] q, int i, int j) {
if (i == j) return; // 避免无意义的交换
int temp = q[i];
q[i] = q[j];
q[j] = temp;
}
}