How can i implement Bubble sort with any comparator that user may pass

I am trying to implement Bubble sort on a Countries Array in c#. My Country class is as shown below-

class Country {

    private string name;
    private string continent;
    private long population; 
    public Country (string name, string continent, long population) {
        this.name = name;
        this.continent = continent;
        this.population = population;
    }


public static void BubbleSort(Country[] countryArray) {

       Country temp;
       int count = countryArray.Length;
        for (int outer = 1; outer <= count; outer++)
        {
            for (int inner = 0; inner < outer - 1; inner++)
            {   Country first = countryArray[inner];
                Country second = countryArray[inner+1];

                if (first.name > second.second)
                {
                    temp = countryArray[inner];
                    countryArray[inner] = countryArray[inner + 1];
                    countryArray[inner + 1] = temp;
                }

            }
            
        }

    }
}

So, i know the code behind bubble sort. I just want it to work when user passes a comparer as an extra argument and even when user does not. Please help me.

I want my Bubble sort function to call like this-

Country.BubbleSort(countryArray, anyComparer());

EDIT: The Bubble sort method is a member function of Country class itself.

Upvotes: 1

Views: 209

Answers (1)

Johan Donne
Johan Donne

Reputation: 3285

First off, there are a number of mistakes in your code:

  • if 'name' is a private field of 'Country', it cannot be accessed in your BubbleSort method unless that method is a member of the Country class (which is not the case in your code). Therefore I adapted your 'Country' class to use public properties.
  • You cannot compare strings in the way you do it in your code (at least not in C#. In my example code below, I used the 'string.Compare' method.
  • There is an error in your implementation of the bubblesort. I leave it up to you to sort that out...

As for your question to have a bubblesort with a comparator as a parameter: that can be easily achieved using a Func-delegate as a parameter. Your adapted code:

    class Country
    {

        public string Name { get; }
        public string Continent { get; }
        public long Population { get; }

        public Country(string name, string continent, long population)
        {
            this.Name = name;
            this.Continent = continent;
            this.Population = population;
        }
    }


    public static void BubbleSort(Country[] countryArray, Func<Country,Country,bool> Comparer)
    {
        Country temp;
        int count = countryArray.Length;
        for (int outer = 1; outer <= count; outer++)
        {
            for (int inner = 0; inner < outer - 1; inner++)
            {
                Country first = countryArray[inner];
                Country second = countryArray[inner + 1];

                if (Comparer(first, second))
                {
                    temp = countryArray[inner];
                    countryArray[inner] = countryArray[inner + 1];
                    countryArray[inner + 1] = temp;
                }
            }
        }
    }

    // and overload with default Compare-function
    public static void BubbleSort(Country[] countryArray)
    {
        BubbleSort(countryArray, (c1, c2) => { return string.Compare(c1.Name, c2.Name) > 0; });
    }

And an example how to call your sorting method:

        static void Main(string[] args)
        {
            var countries = new Country[]
                            {
                               new Country("country1", "Europe", 1000), 
                               new Country("country3", "Asia", 700), 
                               new Country("country2", "Africa", 2000)
                            };

            BubbleSort(countries, (c1,c2) => { return string.Compare(c1.Name, c2.Name) > 0; });

            // or use the overload with default compare-function
            BubbleSort(countries);

            foreach (var item in countries)
            {
                Console.WriteLine($"{item.Name} - {item.Continent} - {item.Population}");
            }
            Console.WriteLine();
            BubbleSort(countries, (c1, c2) => { return c1.Population > c2.Population; });
            foreach (var item in countries)
            {
                Console.WriteLine($"{item.Name} - {item.Continent} - {item.Population}");
            }
        }

This yields the following output:

country1 - Europe - 1000
country2 - Africa - 2000
country3 - Asia - 700

country1 - Europe - 1000
country3 - Asia - 700
country2 - Africa - 2000

In the second part you can see your bubblesort is still not working as it should (but that is beyond the scope of your question and an nice exercise in debugging).

Upvotes: 1

Related Questions