#include <fstream>
#include <cmath>
#include <algorithm>
#include <iostream>
using namespace std;
///// DESCRIPTION
// THIS PROGRAM IMPLEMENTS THE MOST
// POPULAR SORTING ALGORITHMS
// TO ORDER A LIST OF N ELEMENTS
// IN ASCENDINGLY
/////
void qsort(int[], int);
void qsort_aux(int[], int, int);
int qsortPartition(int[], int, int);
void mergeSort(int[], int);
void mergeSort_aux(int[], int, int);
void merge(int v[], int, int, int);
void heapSort(int[], int);
void buildHeap(int[], int);
void heapify(int[], int, int);
void introSort(int[], int);
void introSort_aux(int[], int, int, int, int);
void bubbleSort(int[], int);
void insertionSort(int[], int);
void selectionSort(int[], int);
int main(int argc, char **argv)
{
// INPUT
ifstream indata("algsort.in");
int n;
indata >> n;
int v[n];
for (int i = 0; i < n; i++) {
indata >> v[i];
}
indata.close();
// SORT
qsort(v, n);
//mergeSort(v, n);
//heapSort(v, n);
//introSort(v, n);
//bubbleSort(v, n);
//insertionSort(v, n);
//selectionSort(v, n);
// OUTPUT
ofstream outdata("algsort.out");
for (int i = 0; i < n; i++) {
outdata << v[i] << " ";
}
outdata.close();
return 0;
}
// OPTIMUM ALGORITHMS
int int_compare_asc(const void * a, const void * b) {
return ( *(int*)a - *(int*)b );
}
void q_sort(int v[], int ls,int ld){
if (ls < ld) {
const int middle = ls + (ld - ls) / 2;
int pivot = v[middle];
int i = ls, j = ld;
while(i < j) {
while(i < ld && v[i] < pivot) {
i++;
}
while(j > ls && v[j] > pivot) {
j--;
}
if(i <= j){
swap(v[i], v[j]);
i++; j--;
}
}
//cout << i << " " << j << endl;
q_sort(v, ls, i - 1);
q_sort(v, i, ld);
}
}
void qsort(int v[], int n) {
// STL IMPLEMENTATION
//std::qsort (v, n, sizeof(int), int_compare_asc);
// OWN IMPLEMENTATION
//qsort_aux(v, 0, n - 1);
q_sort(v, 0, n-1);
}
void qsort_aux(int v[], int ls, int ld) {
if (ls < ld) {
int pivotIndex = qsortPartition(v, ls, ld);
qsort_aux(v, ls, pivotIndex - 1);
qsort_aux(v, pivotIndex + 1, ld);
}
}
int qsortPartition(int v[], int ls, int ld) {
const int middle = ls + (ld - ls) / 2;
const int pivot = v[middle];
// move the pivot to the beginning
// of the current sub-array
swap(v[middle], v[ls]);
int i = ls + 1; int j = ld;
while(i <= j) {
while (i <= j && v[i] <= pivot){
i++;
}
while (i <= j && v[j] >= pivot) {
j--;
}
if (i < j) {
swap(v[i], v[j]);
}
}
// put the pivot back in its rightful position
// and return what that position is
swap(v[i - 1], v[ls]);
return i - 1;
}
void mergeSort(int v[], int n) {
mergeSort_aux(v, 0, n - 1);
}
void mergeSort_aux(int v[], int ls, int ld) {
if (ls < ld) {
int middle = ls + (ld - ls) / 2;
mergeSort_aux(v, ls, middle);
mergeSort_aux(v, middle + 1, ld);
merge(v, ls, middle, ld);
}
}
void merge(int v[], int ls, int middle, int ld) {
int i = 0, x = ls, y = middle + 1;
int aux[ls + ld + 1];
while(x <= middle && y <= ld) {
if (v[x] < v[y]) {
aux[i++] = v[x];
x++;
} else {
aux[i++] = v[y];
y++;
}
}
while(x <= middle) {
aux[i++] = v[x++];
}
while (y <= ld) {
aux[i++] = v[y++];
}
// copy the new merged sub-list
// in the original position in the array
for (i = ls; i <= ld; i++) {
v[i] = aux[i - ls];
}
}
void heapSort(int v[], int n) {
buildHeap(v, n);
for (int i = 0; i < n; i++) {
swap(v[n - i - 1], v[0]);
buildHeap(v, n - i - 1);
}
}
void buildHeap(int v[], int n) {
for (int i = n / 2; i > 0; i--) {
heapify(v, i - 1, n);
}
}
void heapify(int v[], int i, int n) {
int root = i;
int left = 2 * i + 1;
int right = 2 * i + 2;
if (left < n && v[root] < v[left]) {
root = left;
}
if (right < n && v[root] < v[right]) {
root = right;
}
if (root != i) {
swap(v[i], v[root]);
heapify(v, root, n);
}
}
void introSort(int v[], int n) {
introSort_aux(v, n, 0, n - 1, log(n) * 2);
}
void introSort_aux(int v[], int n, int ls, int ld, int maxdepth) {
if (ls == ld) {
return;
}
if (maxdepth == 0) {
heapSort(v, n);
} else {
int pivotIndex = qsortPartition(v, ls, ld);
introSort_aux(v, n, ls, pivotIndex - 1, maxdepth - 1);
introSort_aux(v, n, pivotIndex + 1, ld, maxdepth - 1);
}
}
// UNOPTIMUM ALGORITHMS
void bubbleSort(int v[], int n) {
bool isOrdered = false;
while(isOrdered == false) {
isOrdered = true;
for (int i = 0; i < n - 1; i++) {
if (v[i] > v[i+1]) {
swap(v[i], v[i+1]);
isOrdered = false;
}
}
}
}
void insertionSort(int v[], int n) {
for (int i = 1; i < n; i++) {
int j = i, aux = v[i];
while(j > 0 && v[j - 1] > aux) {
v[j] = v[j - 1];
j--;
}
v[j] = aux;
}
}
void selectionSort(int v[], int n) {
for (int i = 0; i < n; i++) {
int min = v[i], minIndex = i;
for (int j = i + 1; j < n; j++) {
if (v[j] < min) {
min = v[j];
minIndex = j;
}
}
swap(v[i], v[minIndex]);
}
}