简体   繁体   中英

In C#, what does a call to Sort with two parameters in brackets mean?

I recently came across an implementation of Djikstra's Shortest Path algorithm online and found the following call. given a List of nodes of type int and a Dictionary of distances, of type , what does the following call mean

nodes.Sort((x, y) => distances[x] - distances[y]);

The full code is as follows:

public List<int> shortest_path(int start, int finish)
{
    var previous = new Dictionary<int, int>();
    var distances = new Dictionary<int, int>();
    var nodes = new List<int>();

    List<int> path = null;

    foreach (var vertex in vertices)
    {
        if (vertex.Item1 == start)
        {
            distances[vertex.Item1] = 0;
        }
        else
        {
            distances[vertex.Item1] = int.MaxValue / 2;
        }

        nodes.Add(vertex.Item1);
    }

    while (nodes.Count != 0)
    {
        nodes.Sort((x, y) => distances[x] - distances[y]);

        var smallest = nodes[0];
        nodes.Remove(smallest);

        if (smallest == finish)
        {
            path = new List<int>();
            while (previous.ContainsKey(smallest))
            {
                path.Add(smallest);
                smallest = previous[smallest];
            }

            break;
        }

        if (distances[smallest] == int.MaxValue)
        {
            break;
        }

        foreach (var neighbor in vertices[smallest].Item2)
        {
            var alt = distances[smallest] + neighbor.Item2;
            if (alt < distances[neighbor.Item1])
            {
                distances[neighbor.Item1] = alt;
                previous[neighbor.Item1] = smallest;
            }
        }
    }

    return path;
}

I searched for the answer a lot but there doesn't seem to be any clear explanation of what it means. I do know that in general in LINQ, a call to Array.Select((x,i)=>...) means that x is the actual element in the array and i is the index of element x in the array, but this doesn't seem to be the case above.

Would appreciate any explanation thanks.

Sorting is implemented by comparing two items at a time.

The two parameters in parentheses are the two items the callback function should compare.

List.Sort Method takes an optional comparison delegate as a comparer.

https://msdn.microsoft.com/en-us/library/w56d4y5z(v=vs.110).aspx

in your example:

(x, y) => distances[x] - distances[y]) is a delegate that Sort uses as a comparer.

if distances[x] - distances[y] < 0; x is bigger;

if distances[x] - distances[y] > 0; y is bigger;

if distances[x] - distances[y] > 0; both are even;

This method will sort the elements in the entire List using the specified System.Comparison. Where System.Comparison is a delegate

public delegate int Comparison<in T>(
    T x,
    T y
)

Think of it like this, you are passing the sort method a way to decide which element in the array is a precedent to the other. The sort function will use the compare function you specified to determine the precedence of each element in the returned sorted list. Therefore this function will get two elements and it will return a value indicating the result of the precendence.

let x be the first argument and y the second argument.

x < y -> the function will return a number less than 0
x = y -> the function will return 0
x > y -> the function will return a number bigger than 0

In conclusion, this function you pass to the Sort method will help the Sort function to sort the array as you wish it should sort it.

In C#, what does a call to Sort with two parameters in brackets mean?

You have this line of code:

nodes.Sort((x, y) => distances[x] - distances[y]);

You are not passing two parameters to the sort method but you are passing one parameter which is a delegate that takes 2 parameters. You are essentially doing the following but using a lambda notation:

var nodes = new List<int>();
nodes.Sort(SortIt);

And here is the SortIt method:

private int SortIt(int x, int y)
{
    return distances[x] - distances[y];
}

Keep in mind if you did it using the above approach, distances will have to be a class level field so the SortIt method can access it. With lambda expressions, this is what you have, it will just capture the distances variable and this is called a closure . Read this article if you want to know what closures are.

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