It is possible to make quicksort `O(n \lg n)` in the worst case by finding the median in linear time and using it to partition the array, this way the partition set always splits the array into equal halves. However the algorithm for finding the median in linear time is not easy to implement and it is not practical for reasonable datasets.
It is also possible to make mergesort in-place using an in-place merging algorithm. Can you think of how to do it?
Quicksort is probably the most widely used sorting algorithm. Jon Bentley gave a talk on “Three Beautiful Quicksorts” at Google. Highly recommended!