import edu.princeton.cs.algs4.StdOut;
import edu.princeton.cs.algs4.StdIn;
public class Merge {
static private final int critical = 7 ;
private Merge (){}
static public void merge (Comparable[] a, int low, int mid, int high) {
assert isSorted(a, low, mid);
assert isSorted(a, mid+1 , high);
if (less(a[mid], a[mid+1 ]))
return ;
int i = 0 ;
while (less(a[i], a[mid+1 ]) && i < mid)
i++;
int j = mid+1 ;
while (less(a[j], a[i]) && i<high )
j++;
int move_right = j - mid - 1 ;
int move_left =mid + 1 - i;
for (int k =i; k <= mid; k++)
assert isSorted(a, low, high);
}
static public void sort (Comparable[] a) {
int high = a.length -1 ;
sort(a, 0 , high);
assert isSorted(a);
}
static private boolean less (Comparable a , Comparable b) {
return a.compareTo(b) < 0 ;
}
static private void InsertSort (Comparable[] a, int low, int high) {
for (int i = low + 1 ; i <= high; i++){
for ( int j = i; j >= low && less(a[j+1 ], a[j]); j --){
exch(a[j+1 ], a[j]);
}
}
}
static private void sort (Comparable[] a, int low, int high) {
if (high - low + 1 < critical) {
InsertSort(a, low, high);
return ;
}
if (high <= low)
return ;
int mid = low + (high - low)/ 2 ;
sort(a, low,mid);
sort(a, mid + 1 , high);
merge(a, low, mid, high);
}
static private void exch (Comparable a, Comparable b) {
Comparable temp = a;
a = b;
b = temp;
}
static private boolean isSorted (Comparable[] a) {
return isSorted(a, 0 , a.length - 1 );
}
static private boolean isSorted (Comparable[] a, int lo, int hi) {
for (int i = lo + 1 ; i <= hi; i++)
if (less(a[i], a[i-1 ])) return false ;
return true ;
}
private static void show (Object[] a) {
for (int i = 0 ; i < a.length; i++) {
StdOut.println(a[i]);
}
}
public static void main (String[] args) {
String[] a = StdIn.readAllStrings();
Merge.sort(a);
show(a);
}
}
private static void sort (Comparable[] a, int lo, int hi) {
if (hi <= lo) return ;
int mid = lo + (hi - lo) / 2 ;
sort(a, lo, mid);
sort(a, mid + 1 , hi);
merge(a, lo, mid, hi);
private static void sort (Comparable[] a) {
int N = a.length;
aux = new Comparable[N];
for (int size = 1 ;size < N; size = size * 2 )
for (int low = 0 ; low < N - size ; low + = size * 2 )
merge(a, low, low +size -1 ; Math.min (low + size * 2 - 1 , N - 1 ));
}