views:

956

answers:

8

Hi

I have 9 values in the form of a matrix and need to compute the median from these values as part of a simulation process. I use quicksort in C++ (i.e qsort()) which results in the process running slow (as this process iterates several times). Is there a better sorting algorithm that I could use? Thanks. Bi.

A: 

Insertion Sort..

On small datasets you can use different algorithms to get optimal performance. QuickSort shines once the dataset grows.

There are different approaches. You can use data structures where you sort on insert, and there are onces where you sort the complete dataset. You just need to find your optimal algorithm.

Makach
Insertion sort should be a smidge faster on random data, shouldn't it?
Steve Jessop
In fact, some quick sorts will use selection sort automatically when the sizes of the partitions or the list gets very small.
Jeremy Powell
@Jeremy Maybe it was insertion sort...
Jeremy Powell
Not to sound overzealous, but you really ought never to "seriously" recommend bubblesort.
Agor
I agree. Insertion sort is a bit easier to write, and runs a bit faster in general. Except in very odd circumstances (like you're not working with random-access memory) bubble sort should never be used.
David Thornley
+1 I agree as well, it was a spur of the moment thing to write - just to make a point. Insertion sort is good choice.
Makach
+3  A: 
  1. As onebyone mentioned there is no need to sort completely to get a median.

  2. STL has sort algorithm which usually can perform comparison inlining. It also has smarter algorithm than guaranteed by qsort, with worstcase of O(NlgN).

EFraim
Hi, Thanks. So I dont need to sort completely to get the median? In that case, is there a better way to get the result? Thanks.
Bi
RE point 2: probably has a trade off in space, though. (like binary tree sort)
Jeremy Powell
@Bi: There is a linear algorithm for median - see the link on onebyone comment.
EFraim
Though granted, the algorithm constants are rather large, and it probably really does not matter for 9 values.
EFraim
@Jeremy: not necessarily. heapsort takes no extra space, and is O(n log n) worst case
newacct
+5  A: 

Only 9 values? Quicksort is overkill.

Perhaps use insertion sort, bubble sort or other simpler sorting algorithms when working with smaller datasets.

Performance

Bubble sort has worst-case and average complexity both О(n²), where n is the number of items being sorted. There exist many sorting algorithms with the substantially better worst-case or average complexity of O(n log n). Even other О(n²) sorting algorithms, such as insertion sort, tend to have better performance than bubble sort. Therefore bubble sort is not a practical sorting algorithm when n is large.

However, granted, you did not even have to sort to get the median as others have suggested.

Floetic
+4  A: 

Using quicksort for only 9 values is going to be rather inefficient. For such a small sample size, you're much better off utilizing a selection sort or replacement sort... there is very little overhead in these sorting methods.

Quicksort and Mergesort really shine once your sample size reaches a threshold, perhaps 50+.

In these situations, I'd write my own code rather than use a built-in function.

hamlin11
+7  A: 

Please please please never recommend bubble sort except to masochists!

For small values, insertion sort is best, and its good for other applications (nearly sorted data of any length).

Edit: cleaned up formatting, emphasizing suggested answer.

Agor
I knew a professor who used to manage a large development team of a software company everyone knows. He tells us he had to take a trip to Australia to fix a customers' performance issues, and when he got there, there was a bubble sort with comments 'should eventually change to something better'. He said he fired the guy that day for costing the company thousand of dollars in support.
Jeremy Powell
@jeremy - I think the manager and QA should have gotten fired - not the developer...
Tim
@time Yeah, I agree. But at least its deterrent enough to know that there are people out there who might fire you for writing that.
Jeremy Powell
other than being slow, what in the world is wrong with a bubble sort? it's quick to implement, easy to do correctly...
San Jacinto
It's just as easy to do an in-place selection or replacement sort. You don't even need to utilize a second array or datastructure. If you can implement a bubble sort quickly, you can implement one of these methods quickly. It might require 30% more "thinking", but it works and it works well.
hamlin11
Bubble sort usage is explained here http://en.wikipedia.org/wiki/Bubble_sort#In_practice
Jeremy Powell
Oooo I never realized Bubble Sort wasn't cache friendly.
Jeremy Powell
+1  A: 

You don't have enough values to work with Quicksort and you should use less advanced algorithms (ex: Bubble sort, Insertion sort, ... explanation here.

There is a cost associated to Quicksort's setup and when you don't have enough values, it's useless to use this beast.

Jodi
Calling Quicksort a beast is... Uh... I don't know. One-liner algorithm cannot be a beast.
EFraim
Err, the only thing I get when I google "one liner quick sort" is a ton of Haskell hits (and this question :P). Can you give me a one liner quick sort in c++? :)
Jeremy Powell
+17  A: 

Sorting to get a median is very inefficient. You could use STL nth_element instead:

#include <algorithm>

// Assuming you keep the elements in a vector v of size len

std::nth_element( v.begin(), v.begin()+len/2, v.end() );
median = v[len/2];

 //... or, if the elements are in a simple array v[len], then

std::nth_element( v, v+len/2, v+len );
median = v[len/2];

Note: the nth_element will modify the vector/array v. Make a copy first if you need to preserve the original.

Igor Krivokon
+3  A: 

The std::sort() algorithm is almost always preferable to qsort(). It's typically easier to use and runs faster.

If you want to get into detail, there's actually a family of sorting algorithms. Stroustrup writes in The C++ Programming Language that std::sort is often not the exact right thing to use. In this case, std::nth_element() is probably what you want.

David Thornley