My solution:
- Take 2 pointers start of array and end of array. 
- Into result array write a min(or max if you need sort in descending) value from both pointers, and shift
pointer to 1 position (start pointer +1 position and end pointer -1
position 
- Repeat till start pointer will be placed after end pointer. 
Complexity of solution is O(N).
Required memory is O(N)
Pseudocode:
function Sort(a)
{
  startPointer = 0;
  endPointer = a.length-1;
  result = new Array of size a.length
  while (startPointer <= endPointer)
  {
    var newValue;
    if (a[startPointer] < a[endPointer])
    {
      newValue = a[startPointer];
      startPointer +1
    }
    else
    {
      newValue = a[endPointer];
      endPointer -1
    }
    result[a.length - startPointer - endPointer] = newValue;
  }
  return result;
}
Solution for updated question:
As solution usde partil sorting of first part of array.
Pointers on (10 and 11)
{10, 12, 14, 16, 15, 13, 11}
Pointers on (12 and 11)
Swap 12 and 11
{10, 11, 14, 16, 15, 13, 12}
Pointers on (14 and 12)
Swap 14 and 12
{10, 11, 12, 16, 15, 13, 14} // Move pointer from 14 to 13 a it lesser.
Now we have sorted {10, 11, 12} and sub problem for {16, 15, 13, 14} (N for sub problem decreased twicely)
Complexity for this algorithm is: O(N) + (N/2) + O(N/4) + ... totally is O(N)
Image for better illustration:
