0

I've written the the selection sort method beneath. I would like to retain the code in general as it's a school exercise, but I understand that there are more correct ways to do it, as with Linq. It works well besides that it only sorts the property PersonalNumber. I can see where the error is the following:

temp = list[i].PersonalNumber;
list[i].PersonalNumber = list[posMin].PersonalNumber;
list[posMin].PersonalNumber = temp;

Is there any way to sort all of the properties contained for each index in the list? Or do I have to write the above code for each property? There are three properties in total.

Full method:

public static void SelectionSort(List<Person> list) {
    // With this method the Person list is sorted in ascending order. 
    //posMin is short for position of min
    int posMin, temp;
    for (int i = 0; i < list.Count - 1; i++) {
        posMin = i;//Set posMin to the current index of array
        for (int j = i + 1; j < list.Count; j++) {
            if (list[j].PersonalNumber < list[posMin].PersonalNumber) {
                //posMin will keep track of the index that min is in, this is needed when a swap happens
                posMin = j;
            }
        }

        //if pos_min no longer equals i than a smaller value must have been found, so a swap must occur
        if (posMin != i) {
            temp = list[i].PersonalNumber;
            list[i].PersonalNumber = list[posMin].PersonalNumber;
            list[posMin].PersonalNumber = temp;
        }
    }
}
Douglas
  • 50,098
  • 9
  • 120
  • 168
Max
  • 339
  • 4
  • 14
  • 3
    You could use Linq, it will sort Lists for you with simple criteria – Alfie Goodacre Apr 07 '16 at 14:59
  • Hi, I'm quite a newbie still. I leave Linq for later. I'm still learning the basics. – Max Apr 07 '16 at 14:59
  • 3
    Linq is your friend for this "sort" of thing :-p http://stackoverflow.com/questions/722868/sorting-a-list-using-lambda-linq-to-objects – ManoDestra Apr 07 '16 at 15:00
  • 2
    Why not swap the Person objects themselves instead of their properties? `temp = list[i]; list[i] = list[posMin]; list[posMin] = temp;` – Dennis_E Apr 07 '16 at 15:00
  • @MaxModestoWallin Right, I had a feeling that you would have used linq if you wanted to, in that case you want an answer that amends your code instead of replacing it? – Alfie Goodacre Apr 07 '16 at 15:01
  • @Dennis_E. I thought so too, but then I got an error: Cannot implicitly convert type 'Uppgifter_kap_12_13_14_15.Person' to 'int' – Max Apr 07 '16 at 15:02
  • @AlfieGoodacre That's correct! – Max Apr 07 '16 at 15:03
  • 1
    @MaxModestoWallin `temp` must be a `Person`, not an `int` if you do that. – Dennis_E Apr 07 '16 at 15:03

3 Answers3

2

It's definitely not something you should do manually (unless you're training your algorithmics skills :) ). It will make your code more complex and harder to maintain.

Just put:

using System.Linq;

and do this:

var sorted = list.OrderByDescending(x => x.PersonalNumber).ToList();

you don't need to be Linq ninja to use it. I also strongly recommend to start using it. I think you can agree it's very easy to read and quite obvious what is it doing.

Ah, and if you're wanting to sort ascending, just use .OrderBy instead of .OrderByDescending.

Jakub Szumiato
  • 1,260
  • 1
  • 13
  • 18
  • Hi and thanks for the answer. I would like to retain the original coding as it's a school exercise, but I'll go with Linq then. – Max Apr 07 '16 at 15:42
2

If you want to sort list in place, just put Sort:

list.Sort((x, y) => x.PersonalNumber.CompareTo(y.PersonalNumber));

To sort in descending order, add -:

list.Sort((x, y) => -x.PersonalNumber.CompareTo(y.PersonalNumber));
Dmitry Bychenko
  • 149,892
  • 16
  • 136
  • 186
0

For most scenarios, you should use one of the built-in functionalities for sorting, such as List<T>.Sort or Enumerable.OrderBy. I'm assuming that you want to retain your own implementation for the sorting algorithm.

You can introduce a key selector function as the second argument to your method:

public static void SelectionSort<TSource, TKey>(
    List<TSource> list, 
    Func<TSource, TKey> keySelector) 
{
    // With this method the list is sorted in ascending order. 
    //posMin is short for position of min
    int posMin;
    for (int i = 0; i < list.Count - 1; i++) {
        posMin = i;//Set posMin to the current index of array
        for (int j = i + 1; j < list.Count; j++) {
            if (keySelector(list[j]) < keySelector(list[posMin])) {
                //posMin will keep track of the index that min is in, this is needed when a swap happens
                posMin = j;
            }
        }

        //if pos_min no longer equals i than a smaller value must have been found, so a swap must occur
        TSource temp;
        if (posMin != i) {
            temp = list[i];
            list[i] = list[posMin];
            list[posMin] = temp;
        }
    }
}

You would then consume this with a lambda expression:

SelectionSort(persons, (Person p) => p.PersonalNumber);
Douglas
  • 50,098
  • 9
  • 120
  • 168