Click here to Skip to main content
Click here to Skip to main content

Generic Quick Sort using anonymous methods

By , 22 Dec 2004
 

Sample Image

Introduction

The code simply implements static generic methods. It does not really solve any problems as there is a sort method in the framework that is probably better than this one. Its purpose is to show the quicksort algorithm and how to use generics and anonymous methods.

Using the code

To use this code, just pass any array and delegate method that can compare items in the array against each other. Notice that I use the keyword delegate as I define an anonymous method. The parameters and return type of this anonymous method (if any) must match the signature of the delegate type expected, in this case Compare.

using System;
using System.Text;

public class Test
{
    public delegate bool Compare<T>(T rhs, T lhs);
    public static void Main()
    {
        Random r = new Random();
        int[] stuff = new int[10];
        for (int i = 0; i < stuff.Length; i++)
            stuff[i] = r.Next(10);
        QuickSort(ref stuff, delegate(int rhs, int lhs){return rhs <= lhs; });
        Console.WriteLine(PrintArray(stuff, 0, stuff.Length));
    }
    public static void QuickSort<T>(ref T[] values, Compare<T> comp)
    {
        QuickSortRecurse(ref values, 0, values.Length, comp);
    }
    public static void Swap<T>(ref T a, ref T b)
    {
        T temp = a;
        a = b;
        b = temp;
    }
    public static string PrintArray<T>(T[] values, int start, int end)
    {
        StringBuilder builder = new StringBuilder();
        for (int i = start; i < end; i++)
        {
            builder.Append(values[i].ToString());
            builder.Append(" ");
        }
        return builder.ToString();
    }
    public static void QuickSortRecurse<T>(ref T[] values, 
           int start, int end, Compare<T> comp)
    {
        if ((end - start) < 2) return;
        if (((end - start) == 2)) 
        {
            if (!comp(values[start], values[end - 1]))
            {
                Swap(ref values[start], ref values[end-1]);
            }
            return;
        }
        int stop = end - 1;
        int i = start + 1;
        while (i < stop)
        {
            while (!comp(values[start], values[i]) && i < stop) i++;
            while (comp(values[start], values[stop]) && stop >= i) stop--;
            if (i < stop)
            {
                Swap(ref values[i], ref values[stop]);
            }
        }
        if (start < stop)
        {
            Swap(ref values[start], ref values[stop]);
        }
        if (start < stop-1)
            QuickSortRecurse(ref values, start, stop, comp);
        if (stop+1 < end)
            QuickSortRecurse(ref values, stop + 1, end, comp);
    }
}

Points of Interest

Generics, as shown in this example, will dynamically derive the type of T when not explicitly stated.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here

About the Author

Doug Coburn
United States United States
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralKernighan and Plaugher's bug lives onmembermdgray27 Dec '04 - 9:21 
The algorithm here has lineage from Kernighan and
Plaugher's generally excellent "Software Tools" including a rather odd bug in the code that was supposed to prevent recursion stack growth beyond log2(element count). It doesn't.
 
This is not to criticise a good C# generics use but that algorithm bug got me when I implimented their quicksort in c++ for an embedded app about 15 years ago. Every once in a while the stack blew up and it took me a long time to find it. What is amazing is how the error has propogated since that original program which I think was written in Ratfor! It was also in early Microswoft quickbasic sample programs.
GeneralRe: Kernighan and Plaugher's bug lives onsussAnonymous27 Jun '05 - 11:25 
Can you document the bug?

GeneralRe: Kernighan and Plaugher's bug lives onmemberBoudino20 Oct '05 - 1:35 
It is an ancient post I have found today, but I hope you sometime answer. Can you describe and explain the bug? Thanks.
GeneralRe: Kernighan and Plaugher's bug lives onmembermdgray20 Oct '05 - 14:36 
This bit me in the butt on a embedded app once.
 
In the original (very old) Kernihan book "Ratfor" he included some ratfor code with a similar structure along with the statement that the stack usage was order Log2(n). There was even a comment in the last section of the original Ratfor code about this. However, this wasn't true. The result is that that quicksort used stack space that, in the worst case (typically an already sorted set) is nested by the full number of elements in the set, rather than log2(n). This logic error was pretty much copied into Microsoft's Quickbasic samples and is widespread. One correct version recurses the shortest segment only, then repartitions the larger segment.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Permalink | Advertise | Privacy | Mobile
Web04 | 2.6.130523.1 | Last Updated 23 Dec 2004
Article Copyright 2004 by Doug Coburn
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid