Sorting numbers in the list without using sort command

152 views (last 30 days)
I'm trying to sort the numbers in the list without using sort command in Matlab. I couldn't find what's wrong with my code.
Here is what I tried:
A= [1 2 4 0 0 8 5 11 0.2]
B=[]
B(1)= min(A)
for i=2:length(A)
A(A==min(A))=[]
B(i)=min(A)
end
fprintf('B')
Result is with an error:
B =
0 0.2000 1.0000 2.0000 4.0000 5.0000 8.0000 11.0000
A =
1×0 empty double row vector
Unable to perform assignment because the left and right sides have a different number of elements.
What I want is:
B =
0 0 0.2000 1.0000 2.0000 4.0000 5.0000 8.0000 11.0000
If "A(A==min(A))=[]" removes just one element in each step, I think the script gives desired sorting.
How can I solve that:
Thanks.
  4 Comments
Jan
Jan on 15 Jan 2019
Edited: Jan on 15 Jan 2019
See "Alternative" in my answer for a comment concerning your comment above.
Akmurat tayirov
Akmurat tayirov on 8 Apr 2021
while true
finished = 1;
for i=1:size(X,2)-1
if X(i)>X(i+1)
c=X(i);
X(i)=X(i+1);
X(i+1)=c;
finished = 0;
end
end
if finished
break
end
end

Sign in to comment.

Answers (2)

Jan
Jan on 14 Jan 2019
Edited: Jan on 15 Jan 2019
You are near already. Instead of removing all occurrences of the current minimal element, it is easier to use both outputs of the min() command, to determine the value and the index of the first minimal element:
A = [1 2 4 0 0 8 5 11 0.2];
B = zeros(size(A)); % Pre-allocate the output
for k = 1:numel(A) % NUMEL is safer than LENGTH
[m, ind] = min(A); % Use both outputs of MIN
A(ind) = []; % Alternatively: A(ind) = inf
B(k) = m;
end
disp(B)
fprintf('B') displays the character B. disp(B) shows the contents of the variable B.
In Matlab i is the imaginary unit, if it is not defined as a variable. Therefore MathWorks recommends to avoid using it as loop counter and I used k.
The pre-allocation and inserting Inf instead of deleting the element of A improve the efficiency: Iteratively growing or shrinking arrays consume a lot of resources. For sorting 10 elements this does not matter, but for a million it does. Of course, if you sort a million numbers, there are smarter algorithms at all.
Here length() works perfect, but it is prone to bugs, when the user does not consider, that the input can be an array also. Then length() replies the size of the longest dimension, and this is rarely useful. So better use either numel or size(x, d) to get the length of a specific dimensions.
Alternative concerning your Comment (link):
B(i)=A(indx(j)) overwrites B(i) in each iteration by the same value. This is a waste of time. This is more efficient using logical indexing (omit the find):
A = [1 2 4 0 0 8]
B = []
for k = 1:numel(A)
indx = (A == min(A))
B = [B, A(indx)];
A(indx) = []
end
Then you do not need an inner loop.
indx(1):indx(length(indx)) is exactly the same as indx.

John D'Errico
John D'Errico on 14 Jan 2019
Edited: Walter Roberson on 14 Jan 2019
Just use sort. ;-) Yeah, I know, it is homework. Not allowed. But you did make a credible effort, and you were close.
You have one major problem, and that is what happens when A has replicated elements. Thus, when min(A)==0, what happens? There are two zeros in A.
This line:
A(A==min(A))=[]
deletes TWO elements of A. But then this line
B(i)=min(A)
stuffs only ONE element into B(i). This will cause problems down the line.
Another problem is you first deleted the minimum element of A, THEN you tried to stuff min(A) into B. But that element was already stepped on and thrown into the bit bucket.
Essentially, your idea cannot work, at least not as you implemented it.
But suppose you reworked it a bit? Do you need to use afor loop? Why not try a while loop instead? Finally, be more careful about the order of things as you wrote your code.
A = [1 2 4 0 0 8 5 11 0.2];
B = [];
while ~isempty(A)
indmin = (A==min(A)); % just use logical indexing to locate the minimal element(s)
B = [B,A(indmin)]; % Append to B, rather than an insertion.
A(indmin) = [];
end
fprintf('B')
So the same essential idea, but now it is robust to replicated elements.
Note that the code I wrote here will be rather inefficient for large vectors, since it grows the vector B dynamically, generally a bad thing. You were doing the same thing though.
Oh. You will want to learn to use semi-colons to terminate your lines.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!