Reputation: 91
I have two row vectors (i_1,i_2,...,i_n) and (b_1,b_2,...,b_n) where i_1 corresponds to b_1. I need to consider the case where the i elements are not necessarily in order so must be sorted, how do I do this while also making sure the b elements are rearranged so that they still correspond to the correct i element. I have the following sorting code that I need to use but am unsure how to adapt it to do what I need it to.
function [ out ] = myMsort( a )
%MYMSORT returns a sorted version of the input row vector, by merging
% Merge sort: running time O(n log n) with n elements to sort
% But really quite inefficient for small n
n=length(a);
if (n==1)
out=a; return
end
out=myMerge(myMsort(a(1,1:floor(n/2))),myMsort(a(1,floor(n/2)+1:n)));
end
Where the function called within this is as follows
function [ out ] = myMerge( a,b )
% MYMERGE: takes two sorted row vectors and produces the (sorted) merge
% running time linear in output size
out=zeros(1,length(a)+length(b)); % Avoid growing array!
j=1;k=1;l=1;
while (j<=length(a))&&(k<=length(b))
if (a(1,j)<b(1,k))
out(1,l)=a(1,j); j=j+1;l=l+1;
else
out(1,l)=b(1,k); k=k+1;l=l+1;
end
end
while (j<=length(a))
out(1,l)=a(1,j); j=j+1;l=l+1;
end
while (k<=length(b))
out(1,l)=b(1,k); k=k+1;l=l+1;
end
end
Any help would be much appreciated.
Upvotes: 1
Views: 745
Reputation: 5945
You can modify the code to accept multiple rows of data, but still just sort all columns based on the values in the first row. This requires only small changes: first, change every instance of length(a)
or length(b)
to size(a,2)
and size(b,2)
. Then make sure in the merge assignments you transfer all elements from that column by using the :
indexing operator, instead of 1
.
function [ out ] = myMsort( a )
n=size(a,2);
if (n==1)
out=a;
return
end
out=myMerge(myMsort(a(:,1:floor(n/2))),myMsort(a(:,floor(n/2)+1:n)));
end
function [ out ] = myMerge( a,b )
out=zeros(size(a,1),size(a,2)+size(b,2)); % Avoid growing array!
j=1;k=1;l=1;
while (j<=size(a,2))&&(k<=size(b,2))
if (a(1,j)<b(1,k))
out(:,l)=a(:,j);
j=j+1;l=l+1;
else
out(:,l)=b(:,k);
k=k+1;l=l+1;
end
end
while (j<=size(a,2))
out(:,l)=a(:,j);
j=j+1;l=l+1;
end
while (k<=size(b,2))
out(:,l)=b(:,k);
k=k+1;l=l+1;
end
end
Now you can run the code like so:
n = 100;
i = rand([1 n]);
b = rand([1 n]);
out = myMsort([i;b]);
And out
will be a matrix of two rows: row 1 is the sorted values of i
and row 2 is the corresponding values from b
.
Upvotes: 1
Reputation: 2359
Just little modification, here my example :
a = [12,4,1,2,8,7];
and into myMsort, I change :
out=myMerge(myMsort(a(1:floor(n/2))),myMsort(a(floor(n/2)+1:n)));
where all line are already sorted.
I don't really understand the part a is two row
EDIT
here the full myMsort function :
function [ out ] = myMsort( a )
%MYMSORT returns a sorted version of the input row vector, by merging
% Merge sort: running time O(n log n) with n elements to sort
% But really quite inefficient for small n
a = reshape(a,1,size(a,1)*size(a,2));
n=length(a);
if (n==1)
out=a; return
end
out=myMerge(myMsort(a(1:floor(n/2))),myMsort(a(floor(n/2)+1:n)));
end
Note that i'm using reshape to make a single row array. You can do it by yourself with another function. the problem is with the recursion your out need to be 2 row vector but it not when myMerge return.
Upvotes: 0