简体   繁体   中英

Sort Array in c#, even numbers in descending and odd numbers in ascending without using predefined sort function

I want to sort the given array using C#, like even numbers in descending and odd numbers in ascending without using the build in sort functionality. I want the array to be sorted in the same given array, first even numbers then the odd numbers.

Example: given array is

int[] arr = {1,2,3,4,5,6,7,8}; 

then I want this to be sorted like

arr = {8,6,4,2,1,3,5,7};

I tried the below code.

static void Main(string[] args)
    {
        int[] arr = { 1, 2, 3, 4 };
        SortArray(arr);
        foreach (int i in arr)
        {
            Console.WriteLine(i);
        }
        Console.ReadKey();
    }

    private static void SortArray(int[] arr)
    {
        int temp = 0;
        for (int i = 0; i < arr.Length - 1; i++)
        {
            for (int j = 1; j<arr.Length; j++)
            {
                if (arr[i] < arr[j])
                {
                    if (arr[j] % 2 == 0)
                    {
                        temp = arr[i];
                        arr[i] = arr[j];
                        arr[j] = temp;
                    }
                }
            }
        }
    }

Output: 4 2 3 1
Expected Output: 4 2 1 3

You can use any sortalgorithm you want, but you just need to adapt the comparison function a little bit to respect your requirements. I'll do an example for a bubble sort like algorithm

void sortArray(int[] a) {
  for (int j = a.Length; j > 0; j--) {
    for (int i = 0; i < j - 1; i++) {
      if (greaterThan(a[i], a[i+1])) {
        var tmp = a[i];
        a[i] = a[i+1];
        a[i+1] = tmp;
      }
    }
  }
}

The comparison function greaterThan(a,b) returns true if a should be considered greater then b and takes into account all your requirements for the sorting:

  • even numbers before odd numbers. So if one is even and the other is odd, greaterThan returns true, only if the second is even, ie "smaller".
  • even numbers descending. So if both numbers are even, greaterThan returns true if the first one is less then the second one (to reverse order)
  • odd numbers ascending. So if both numbers are odd, greaterThan return true if the first one is greater then the second one (to preserve order)
bool greaterThan(int a, int b) {
  bool aeven = a % 2 == 0;
  bool beven = b % 2 == 0;
  
  if (aeven ^ beven)  //one is even the other is odd
    return beven;

  //here both are even or both are odd
  //so if a is even, so is b, if a is odd, so is b
  return aeven 
    ? a < b //sort even numbers descending, thus invert comparision
    : a > b; //sort odd numbers ascending
}

The matter is what comparison to perform. Any sorting algorithm is suitable, as long as it uses the correct comparison criteria.

Current comparison criteria are:

  1. Even numbers before odd numbers
  2. Greater even numbers before smaller ones
  3. Smaller odd numbers before greater ones

Choose your favorite sorting algorithm and invoke a comparer that apply those criteria.

Main comparison, just a Comparer for ease of use, but you can extract the Compare method, make it static, and use it alone:

public class EvenOddComparer : Comparer<int>
{
    public override int Compare(int value1, int value2)
    {
        // returns -1 if value1 must be placed before value2
        // returns +1 if value1 must be placed after value2
        // returns 0 if value1 equals value2

        var even1 = value1 % 2 == 0;
        var even2 = value2 % 2 == 0;
        // first is even and second is odd
        if (even1 && !even2)
            return -1;
        // first is odd and second is even
        if (!even1 && even2)
            return +1;

        // both are even
        if (even1)
            return -value1.CompareTo(value2); // descending
        // both are odd
        else
            return value1.CompareTo(value2); // ascending
    }
}

Sorting method, that receives the array of values and a reference to the comparer. You can remove the comparer parameter and invoke the comparison method of your choice directly instead of comparer.Compare . Here we have a Bubble sort, just for simplicity:

public static void Sort(int[] values, Comparer<int> comparer)
{
    for (int ixItem1 = 0; ixItem1 < values.Length - 1; ixItem1++)
        for (int ixItem2 = ixItem1 + 1; ixItem2 < values.Length; ixItem2++)
        {
            var item1 = values[ixItem1];
            var item2 = values[ixItem2];

            var needSwap = comparer.Compare(item1, item2) > 0;
            if (needSwap)
            {
                values[ixItem1] = item2;
                values[ixItem2] = item1;
            }
        }
}

Sample usage:

var values = new[] { 8, 3, 1, 5, 2, 6, 7, 4 };
Sort(values, new EvenOddComparer());

As OP asked for an answer " without using the build in sort functionality ", try this:

using System;
using System.Collections.Generic;

class MainClass {
static void Main(string[] args)
    {
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 };
        SortArray(arr);
        foreach (int i in arr)
        {
            Console.WriteLine(i);
        }
        Console.ReadKey();
    }

    private static void SortArray(int[] arr)
    {
        int temp = 0;
        List<int> listEVENs = new List<int>();
        List<int> listODDs = new List<int>();

        // split array into EVEN and ODD numbers, using LIST because it is easier
        for (int i = 0; i < arr.Length ; i++)
        {
          if (arr[i] % 2 == 0)
          {
              listEVENs.Add(arr[i]);
          } else {
              listODDs.Add(arr[i]);
          }
        }

        // convert the EVEN and ODD lists back to arrays
        int[] arrEVENs = listEVENs.ToArray();
        int[] arrODDs = listODDs.ToArray();

        // Manually sort (descending) even number array without using built-in functions
        for(int i=0; i<arrEVENs.Length; i++)
            {
                for(int j=i+1; j<arrEVENs.Length; j++)
                {
                    
                    if(arrEVENs[j] > arrEVENs[i])
                    {
                        temp = arrEVENs[i];
                        arrEVENs[i] = arrEVENs[j];
                        arrEVENs[j] = temp;
                    }
                }
            }        

        // Manually sort (ascending) ODD number array without using built-in functions
        for(int i=0; i<arrODDs.Length; i++)
            {
                for(int j=i+1; j<arrODDs.Length; j++)
                {
                    if(arrODDs[j] < arrODDs[i])
                    {
                        temp = arrODDs[i];
                        arrODDs[i] = arrODDs[j];
                        arrODDs[j] = temp;
                    }
                }
            }        

        // concatenate the EVEN and ODD number arrays
        Array.Resize(ref arr, (arrEVENs.Length + arrODDs.Length));
        arrEVENs.CopyTo(arr, 0);
        arrODDs.CopyTo(arr, arrEVENs.Length);

        
    }
}

OUTPUT:

8
6
4
2
1
3
5
7

I think I found the answer.

    class Program
{
    static void Main(string[] args)
    {
        int[] arr = { 1, 2, 3, 4, 5, 6, 7, 8 };
        SortArray(arr);
        foreach (int i in arr)
        {
            Console.WriteLine(i);
        }
        Console.ReadKey();
    }

    private static void SortArray(int[] arr)
    {
        int temp = 0;
        for (int i = 0; i < arr.Length - 1; i++)
        {
            for (int j = i + 1; j < arr.Length; j++)
            {
                if (arr[i] < arr[j])
                {
                    temp = arr[i];
                    arr[i] = arr[j];
                    arr[j] = temp;
                }
            }
        }
        for (int i = 0; i < arr.Length - 1; i++)
        {
            for (int j = i + 1; j < arr.Length; j++)
            {
                if (arr[i] % 2 != 0)
                {
                    temp = arr[j];
                    arr[j] = arr[i];
                    arr[i] = temp;
                }
            }
        }
    }
}

Output:

8
6
4
2
1
3
5
7

Thanks for all your help.

int[] arr = { 1, 2, 3, 4 };
var sortedArray = arr.Where(item => item % 2 == 0).OrderByDescending(item => item).Union(arr.Where(item => item % 2 != 0).OrderBy(item => item));            
foreach (int i in sortedArray) {
    Console.WriteLine(i);
}

Where:

  • arr.Where(item => item % 2 == 0) gets the even values
  • .OrderByDescending(item => item) order them descending
  • arr.Where(item => item % 2 != 0) gets the odd values
  • .OrderBy(item => item) order them ascending
  • Union joins the 2 lists together

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