简体   繁体   中英

Given a set of objects that have 2 values. Sort the set with respect to the 1st value and then with the 2nd value

Eg.:

{2,3},{1,2},(2,2},{3,1},{2,1} to {1,2},{2,1},{2,2},{2,3},{3,1}

Here's what I'm thinking:

Do a merge sort on the first column of values. Iterate over the set to see if there are any duplicate values in the first column. If there are, enqueue them onto a list.

Merge sort this list on the second column and then integrate them into the main set. While it does seem feasible to do, it seems overly complicated. This should run in O(NlogN) , so if somebody can think of a faster/same complexity algorithm that's also simpler, please post it!

Thanks!

Simply implement a Comparator<T> which compares any two objects of your type by first comparing the first field, and then moving on to the second field if the first fields are equal. You can then copy the set into a list, call Collections.sort and give it the list and your comparator. There's no need to implement sorting yourself.

The comparator would be something like:

public class TwoFieldComparator implements Comparator<Foo>
{
    public int compare(Foo first, Foo second)
    {
        // TODO: null checks
        int firstComparison = Integer.compare(first.x, second.x);
        return firstComparison != 0 ? firstComparison
                                    : Integer.compare(first.y, second.y);
    }
}

Alternatively, you could make your class implement Comparable<T> in the same sort of way.

What you have to do is performing a stable sort on the second column then once more on the first column.

If the range of the numbers can be determined, O(N) can be achieved with some linear sort.

EDIT:

Take 'merge sort' as an example(for it's stable):
1, Run a merge sort on the second column, then number pairs will be arranged according to the value of second column.
2, Run a merge sort again on the first column, number pairs will be arranged in the order of first column value. However, because the sorting method is stable, that means if the first number is the same, the second number will be sorted as well(we did it in the first sort).

Thus, the num pair array is in order now. No more action is needed.
Merge sort is O(NlogN), thus 2*O(NlogN) is still O(NlogN).

EDIT2:
Well, I might make this problem complicated. Even if the sorting method is needed to be implemented by our own, as long as the data stucture has been determined, filling the compare code by Jon Skeet in the corresponding part of the hand-make sorting method will be the most convenient way.

As you mentioned in one of your commments, this is interview question. Solution by John Skeet shows that you don't have to worry about having two values in your item - just implement correct comparator.

Assuming that you are asked this at 2011, it would be good do find out how your sort is meant to be used. Depending on environment where this sort will be used, you may consider parallel processing (using multiple threads). That may drive your choice of sorting algorithm.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM