3
\$\begingroup\$

Here is my Implementation. It is I think almost like algorithm.

 public static uint[] CountingSort(uint[] A ,uint max)
        {
            uint[] B = new uint[A.Length];
            int[] c = new int[max +1 ];
            for (int j = 0; j < A.Length; j++)
                c[A[j]]++;
            for (int i = 1; i < max + 1; i++)
                c[i] += c[i - 1];
            for (int j = A.Length-1 ; j>=0; j--)
                B[--c[A[j]]] = A[j];


            return B;
        }
\$\endgroup\$
7
\$\begingroup\$

Var

Use implicit typing when the right-hand side of the declaration makes the type obvious.

uint[] B = new uint[A.Length];

should be

var B = new uint[A.Length];

Naming

Single character variable names are some of the least useful names you could give your variables. Your variables have a purpose. Name them appropriately using these purposes.

B means nothing.

Spacing

Give your code some room to breathe, the compiler will cut it out anyway when it gets to the optimization stage, and there's no sense making it harder to read for maintenance programmers. Also consider surrounding your loop bodies with braces. This way if somebody came in and added a line to the loop body, it wouldn't break.

Design

Use foreach when iterating over every item in a collection, it more accurately conveys your meaning.

Secondly, I cannot find a use for manually specifying max. Instead you should calculate this using:

var max = A.Max();

All things combined, I recommend:

public static uint[] CountingSort(uint[] unsorted)
    {
        var max = unsorted.Max();
        var sorted = new uint[A.Length];
        var count = new int[max +1];

        foreach(var unsortedValue in unsorted)
        {
            count[unsortedValue]++;
        }

        for (var i = 1; i < max + 1; i++)
        {
            count[i] += count[i - 1];
        }

        for (var j = unsorted.Length-1 ; j>=0; j--)
        {
            sorted[--count[unsorted[j]]] = unsorted[j];
        }

        return sorted ;
    }

Optionally

You could consider making this method an extension method of the uint[] type:

public static uint[] CountingSort(this uint[] unsorted)
    {
        var max = unsorted.Max();
        var sorted = new uint[unsorted.Length];
        var count = new int[max +1];

        foreach(var unsortedValue in unsorted)
        {
            count[unsortedValue]++;
        }

        for (var i = 1; i < max + 1; i++)
        {
            count[i] += count[i - 1];
        }

        for (var j = unsorted.Length-1 ; j>=0; j--)
        {
            sorted[--count[unsorted[j]]] = unsorted[j];
        }

        return sorted ;
    }

Then you can call the method like this:

var sorted = unsorted.CountingSort();

But this is optional and depends on your desired use cases.

Secondly, consider using an interface such as IList to allow callers of your method more freedom when specifying data types:

    public static IList<uint> CountingSort(this IList<uint> unsorted)
    {
        var max = unsorted.Max();
        var sorted = new uint[unsorted.Count];
        var count = new int[max +1];

        foreach(var unsortedValue in unsorted)
        {
            count[unsortedValue]++;
        }

        for (var i = 1; i < max + 1; i++)
        {
            count[i] += count[i - 1];
        }

        for (var j = unsorted.Count-1 ; j>=0; j--)
        {
            sorted[--count[unsorted[j]]] = unsorted[j];
        }

        return sorted;
    }

Now you can call:

new List<uint>().CountSort();
new uint[].CountSort();
new Collection<uint>().CountSort();

With way more flexibility.

\$\endgroup\$
4
  • 3
    \$\begingroup\$ The use of var as opposed to explicit typing is personal preference, not at all essential. Personally, I actually prefer explicit typing. \$\endgroup\$ – ArtOfCode Dec 3 '15 at 14:19
  • 1
    \$\begingroup\$ Implicit typing makes it really hard when reading code outside the IDE and the value is assigned to the return of a custom method. I myself too prefer explicit typing and don't see any real profit in implicit typing and only use it when dealing with anonymous types. \$\endgroup\$ – Oguz Ozgul Dec 3 '15 at 16:38
  • 2
    \$\begingroup\$ As I said above, implicit typing should be used "when the right-hand side of the declaration makes the type obvious". Emphasis on " right-hand side of the declaration makes the type obvious". If var is making it harder to read without an IDE, you're using it wrong. \$\endgroup\$ – Nick Udell Dec 3 '15 at 17:26
  • \$\begingroup\$ Nice explanation of using var \$\endgroup\$ – Syed Qasim Ahmed Dec 4 '15 at 11:42

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.