user3058633
user3058633

Reputation: 91

MatLab: Sorting two row vectors

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

Answers (2)

aganders3
aganders3

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

Vuwox
Vuwox

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

Related Questions