#include #include #include using namespace std; int n, a[1000001]; int a1[1000001], a2[1000001]; void in() { scanf("%d", &n); for (int i = 0; i < n; i++) scanf("%d", &a[i]); } //Partitioning this way is less effective because we need additional memory to store elements //which are smaller than the pivot and also elements which are bigger than the pivot. /*int partitionn(int l, int r) { int pivot = a[l + (r - l) / 2], index = 0; swap(a[l], a[l + (r - l) / 2]); int sa1 = 0, sa2 = 0; for (int i = l; i < r; i++) { if (a[i] <= pivot) a1[sa1++] = a[i]; else a2[sa2++] = a[i]; } int ind = l; for (int i = 1; i < sa1; i++) a[ind++] = a1[i]; a[ind++] = pivot; for (int i = 0; i < sa2; i++) a[ind++] = a2[i]; return l + sa1 - 1; }*/ int partitionn(int l, int r) //This partitioning is optimal because we do not need to use any additional memory. { int pivot = a[l + (r - l) / 2]; swap(a[l], a[l + (r - l) / 2]); int ind = l; for (int i = l + 1; i < r; i++) if (a[i] <= pivot) { ind++; swap(a[i], a[ind]); } swap(a[l], a[ind]); return ind; } void quickSort(int l, int r) { if (r - l <= 1) return; int index = partitionn(l, r); quickSort(l, index); quickSort(index + 1, r); } void print() { for (int i = 0; i < n - 1; i++) printf("%d ", a[i]); printf("%d\n", a[n - 1]); } int main() { in(); random_shuffle(a, a + n); quickSort(0, n); print(); return 0; }