I am working on analysis of sorting algorithms by plotting graphs in MATLAB. Below is my quick sort code. When I run it it is giving this error:
Maximum recursion limit of
500
reached. Useset(0,'RecursionLimit', N)
to change the limit. Be aware that exceeding your available stack space can crash MATLAB and/or your computer. Error in ==> quickSort
Why does this error occur? Is there anything wrong in my code?
function [ar] = quickSort(ar, low, high)
if low < high
[ar, q] = parti(ar, low, high);
ar = quickSort(ar, low, q - 1);
ar = quickSort(ar, q + 1, high);
end
end
function [ar, i] = parti(ar, p, r)
x = ar(r);
i = p - 1;
for j = p : r
if ar(j) <= x
i = i + 1;
if i ~= j
tmp = ar(i);
ar(i) = ar(j);
ar(j) = tmp;
end
end
end
i = i + 1;
tmp = ar(i);
ar(i) = ar(r);
ar(r) = tmp;
end
I am calling this function using
ar = [7,7,3,0,3,1,4,7,5,6]
quickSort(ar, 1, 10)
In the function
parti
, to partition the array based on the pivot, you are including the pivot itself when trying to determining it's correct position.This is leading in an infinite recursion in some cases, as the pivot just keeps swapping between adjacent locations, as it is comparing with itself.
Two solutions:
Solution 1:
Solution 2:
I've gone into some depth here about optimising your use of MATLAB, how you should better leverage recursive functions and a redraft of your code. To skip to the working redraft of a quicksort function, see the 2nd and 4th code blocks below
It isn't helping that in your function you're using
low
andhigh
indices to keep track of your partitioning. The whole point of using a recursive quick sort function is this:ar(p)
from the arrayar
ar(p)
and one with values greater thanar(p)
. Equal values can go in either array, as they will remain next to the pivot.The lists are self-similar, by which I mean treat each sub-list as its own list which needs sorting, not part of a larger list! You don't need to keep track of indices (which end up confusing when you're 3 recursions deep), just analyse each list on its own.
You may find the Wikipedia article useful as it details these 3 points, as well as suggesting some schemes for optimally picking the pivot. In the below code, I just choose the middle element.
Additionally, your partitioning function
parti
is really inefficient. In MATLAB, if you find yourself looping through every index of an array then you could probably speed things up. Instead, vectorize your code using logical indexing!At the very least, learn some more about indexing in the documentation because you can do neat things like this:
Edit: Although this demonstrates a more "MATLAB-esque" way of doing things, you incur a performance hit assigning elements like this, so if you don't mind longer code then feel free to use temps!
You can replace all of your code with this 7 line function, which will be much quicker. I've added comments to explain the logic...
This can be run as in your test:
We could make this even shorter by not explicitly declaring
smaller
andlarger
, as well as always choosingp=1
(although that is the worst case for already sorted arrays).