繁体   English   中英

c#中的数组排序,偶数降序,奇数升序,不使用预定义的排序函数

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

我想使用 C# 对给定数组进行排序,例如降序偶数和升序奇数,而不使用内置的排序功能。 我希望数组在同一个给定数组中排序,首先是偶数,然后是奇数。

示例:给定的数组是

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

然后我希望它像这样排序

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

我试过下面的代码。

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

您可以使用任何您想要的排序算法,但您只需要稍微调整比较函数以符合您的要求。 我会做一个像算法一样的冒泡排序的例子

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;
      }
    }
  }
}

如果a应该被认为大于b并考虑到您对排序的所有要求,则比较函数greaterThan(a,b)返回true

  • 偶数在奇数之前。 所以如果一个是偶数而另一个是奇数, greaterThan返回真,只有当第二个是偶数时,即“更小”。
  • 偶数递减。 因此,如果两个数字都是偶数,则如果第一个数字小于第二个数字,则greaterThan返回真(颠倒顺序)
  • 奇数升序。 因此,如果两个数字都是奇数,如果第一个数字大于第二个数字(以保持顺序),则greaterThan返回真
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
}

问题是要执行什么比较。 任何排序算法都是合适的,只要它使用正确的比较标准。

目前的比较标准是:

  1. 偶数在奇数之前
  2. 在较小的数字之前更大的偶数
  3. 在较大的奇数之前较小的奇数

选择您最喜欢的排序算法并调用应用这些标准的比较器。

主要比较,只是一个Comparer的易用性,但可以提取的Compare方法,使静态的,单独使用它:

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
    }
}

排序方法,接收值数组和对比较器的引用。 您可以删除comparer参数并直接调用您选择的比较方法而不是comparer.Compare 这里我们有一个冒泡排序,只是为了简单起见:

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;
            }
        }
}

示例用法:

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

由于 OP 要求“不使用内置排序功能”的答案,请尝试以下操作:

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);

        
    }
}

输出:

8
6
4
2
1
3
5
7

我想我找到了答案。

    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;
                }
            }
        }
    }
}

输出:

8
6
4
2
1
3
5
7

感谢你的帮助。

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);
}

在哪里:

  • arr.Where(item => item % 2 == 0)获取偶数值
  • .OrderByDescending(item => item)按降序排列
  • arr.Where(item => item % 2 != 0)得到奇数
  • .OrderBy(item => item)按升序排列
  • Union将 2 个列表连接在一起

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM