如何让我的快速排序算法按升序和降序对数组进行排序?

问题描述:

目前我的快速排序算法在情况1中按照升序对数组进行排序,但是我希望使用户选择选项2(情况2),然后按降序对数组进行排序。我必须为每种情况创建2个独立的算法吗?还是有更简单更有效的方法?如何让我的快速排序算法按升序和降序对数组进行排序?

欣赏帮助。

static void Main(string[] args) 
    { 
     Console.WriteLine("Analysis of Seismic Data.\n"); 



     Console.WriteLine("Selection of Arrays:"); 
     //Display all the options. 
     Console.WriteLine("1-Year"); 
     Console.WriteLine("2-Month"); 
     Console.WriteLine("3-Day"); 
     Console.WriteLine("4-Time"); 
     Console.WriteLine("5-Magnitude"); 
     Console.WriteLine("6-Latitude"); 
     Console.WriteLine("7-Longitude"); 
     Console.WriteLine("8-Depth"); 
     Console.WriteLine("9-Region"); 
     Console.WriteLine("10-IRIS_ID"); 
     Console.WriteLine("11-Timestamp\n\n"); 

     Console.WriteLine("Use numbers to select options."); 
     //Read in user's decision. 
     Console.Write("Select which array is to be analysed:"); 
      int userDecision = Convert.ToInt32(Console.ReadLine()); 

     //Selected which array is to be analyzed 
      switch (userDecision) 
      { 
       case 1: 
        Console.WriteLine("\nWould you like to sort the Array in Ascending or Descending order?"); 
        Console.WriteLine("1-Ascending"); 
        Console.WriteLine("2-Descending"); 
        //Create another switch statement to select either ascending or descending sort. 
        int userDecision2 = Convert.ToInt32(Console.ReadLine()); 
        switch (userDecision2) 
        { 
         case 1: 
         //Here algorithm sorts my array in ascending order by default. 
         QuickSort(Years); 
         Console.WriteLine("Contents of the Ascending Year array: "); 
         foreach (var year in Years) 
         { 
          Console.WriteLine(year); 
         } 
         break; 
         case 2: 
         //How do I sort the same array in Descending order when Option 2 is selected? 
         //QuickSort(Years) Descendingly. 
          Console.WriteLine("Contents of the Descending Year array: "); 
          foreach (var year in Years) 
          { 
           Console.WriteLine(year); 
          } 
          break; 

        } 
        break; 
       case 2: 
        Console.WriteLine("\nWould you like to sort the Array in Ascending or Descending order?"); 
        Console.WriteLine("1-Ascending"); 
        Console.WriteLine("2-Descending"); 
        //Create another switch statement to select either ascending or descending sort. 
        int userDecision3 = Convert.ToInt32(Console.ReadLine()); 
        switch (userDecision3) 
        { 
         case 1: 
         QuickSort(Years); 
         Console.WriteLine("Contents of the Ascending Month array: "); 
         foreach (var month in Months) 
         { 
          Console.WriteLine(month); 
         } 
         break; 
         case 2: 
         //Same problem, how do I sort it in descending order? 
          Console.WriteLine("Contents of the Descending month array: "); 
         foreach (var month in Months) 
         { 
          Console.WriteLine(); 
         } 
         break; 
        } 
        break; 


     } 

    } 
    public static void QuickSort<T>(T[] data) where T : IComparable<T> 
    { 
     Quick_Sort(data, 0, data.Length - 1); 
    } 

    public static void Quick_Sort<T>(T[] data, int left, int right) where T : IComparable<T> 
    { 
     int i, j; 
     T pivot, temp; 
     i = left; 
     j = right; 
     pivot = data[(left + right)/2]; 
     do 
     { 
      while ((data[i].CompareTo(pivot) < 0) && (i < right)) i++; 
      while ((pivot.CompareTo(data[j]) < 0) && (j > left)) j--; 
      if (i <= j) 
      { 
       temp = data[i]; 
       data[i] = data[j]; 
       data[j] = temp; 
       i++; 
       j--; 
      } 
     } while (i <= j); 
     if (left < j) Quick_Sort(data, left, j); 
     if (i < right) Quick_Sort(data, i, right); 
    } 
+0

您也可以传递决定排序顺序的参数器,但例如,在Linq,微软的开发人员决定创建一个自己的方法'OrderByDescending()' – fubo

+0

我不允许使用内置的排序方法 – Ulfren

你可以改变你快速排序的方法来接受IComparer<T> comparer,和然后用它来进行比较。

然后,如果您需要默认比较订单,则可以使用Comparer<T>.Default,或者您可以使用Comparer<T>.Create()来创建自定义(例如反转)比较。

可编译例子:

using System; 
using System.Collections.Generic; 

namespace ConsoleApp1 
{ 
    class Program 
    { 
     static void Main() 
     { 
      int[] data = {6, 7, 2, 3, 8, 1, 9, 0, 5, 4}; 

      QuickSort(data); 

      Console.WriteLine(string.Join(", ", data)); // Prints 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 

      QuickSort(data, Comparer<int>.Create((a, b) => b.CompareTo(a))); 

      Console.WriteLine(string.Join(", ", data)); // Prints 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 
     } 

     public static void QuickSort<T>(T[] data) 
     { 
      Quick_Sort(data, 0, data.Length - 1, Comparer<T>.Default); 
     } 

     public static void QuickSort<T>(T[] data, IComparer<T> comparer) 
     { 
      Quick_Sort(data, 0, data.Length - 1, comparer); 
     } 

     public static void Quick_Sort<T>(T[] data, int left, int right, IComparer<T> comparer) 
     { 
      int i, j; 
      T pivot, temp; 
      i = left; 
      j = right; 
      pivot = data[(left + right)/2]; 
      do 
      { 
       while ((comparer.Compare(data[i], pivot) < 0) && (i < right)) i++; 
       while ((comparer.Compare(pivot, data[j]) < 0) && (j > left)) j--; 
       if (i <= j) 
       { 
        temp = data[i]; 
        data[i] = data[j]; 
        data[j] = temp; 
        i++; 
        j--; 
       } 
      } while (i <= j); 
      if (left < j) Quick_Sort(data, left, j, comparer); 
      if (i < right) Quick_Sort(data, i, right, comparer); 
     } 
    } 
} 

这有两个好处:

  1. 类型T并不需要实现IComparable<T>。您可以传入进行比较的IComparer<T>对象。
  2. 您可以通过传递不同的自定义IComparer<T>对象以多种方式对相同的数据进行排序。

这是由一些LINQ的IEnumerable的扩展所采用的方法,例如Enumerable.OrderBy()

+0

感谢您的解决方案。我是编程新手,还没有学习过接口。我应该研究什么才能更好地理解您在此处展示的具体解决方案?此解决方案也使用任何内置的排序和搜索功能,因为我不允许在我的任务中使用这些功能。 – Ulfren

+0

@IllimarIssak它没有使用任何内置的排序或搜索;它只是使用一个接口来指定与元素进行比较的方式。欲了解更多信息,请参阅['IComparer '](https://msdn.microsoft.com/en-us/library/8ehhxeaf(v = vs.110).aspx) –

添加参数,允许改变比较的结果

(data[i].CompareTo(pivot) < 0) 
and 
(pivot.CompareTo(data[j]) < 0) 

一个简单的方法:参数descending +1/-1和使用

data[i].CompareTo(pivot) * descending < 0 

只是平添几分奶油对@Matthew沃森回答。在阅读@Illimar的文章后,他想让用户选择以升序模式还是降序模式对数组进行排序。我刚才编辑@Matthew工作拿出了以下内容:

using System; 
    using System.Collections.Generic; 
    using System.Threading; 

    namespace Test1 
    { 

      class Program 
    { 
    static void Main(string[] args) 
    { 
     MySorter(); 
    } 

    static void MySorter() 

    { 
     int[] data = MyArray(); 
     Console.WriteLine(); 
     Console.WriteLine("Chose 1 to sort Ascending or 2 to sort Descending:"); 
     //int choice = Console.Read(); 
     ConsoleKeyInfo choice = Console.ReadKey(); 
     Console.WriteLine(); 
     if (choice.Key == ConsoleKey.D1 || choice.Key == ConsoleKey.NumPad1) 
     { 
      QuickSort(data); 
      string result = string.Join(", ", data); 
      Console.WriteLine(result); 
      Thread.Sleep(4000); 
     } 
     else if (choice.Key == ConsoleKey.D2 || choice.Key == ConsoleKey.NumPad2) 
     { 
      QuickSort(data, Comparer<int>.Create((a, b) => b.CompareTo(a))); 
      Console.WriteLine(string.Join(", ", data)); 
      Thread.Sleep(4000); 
     } 
     else 
     { 
      Console.WriteLine("wrong input."); 
      Thread.Sleep(2000); 
      Environment.Exit(0); 
     } 
    } 

    public static int[] MyArray() 
    { 
     Console.WriteLine("Enter a total of 10 numbers to be sorted: "); 
     int[] InputData = new int[10]; 
     for (int i = 0; i < InputData.Length; i++) 
     { 
      var pressedkey = Console.ReadKey(); 
      int number; 
      bool result = int.TryParse(pressedkey.KeyChar.ToString(), out number); 
      if (result) 
      { 
       InputData[i] = number; 
      } 

     } 

     return InputData; 
    } 

    public static void QuickSort<T>(T[] data) 
    { 
     Quick_Sort(data, 0, data.Length - 1, Comparer<T>.Default); 
    } 

    public static void QuickSort<T>(T[] data, IComparer<T> comparer) 
    { 
     Quick_Sort(data, 0, data.Length - 1, comparer); 
    } 

    public static void Quick_Sort<T>(T[] data, int left, int right, IComparer<T> comparer) 
    { 
     int i, j; 
     T pivot, temp; 
     i = left; 
     j = right; 
     pivot = data[(left + right)/2]; 
     do 
     { 
      while ((comparer.Compare(data[i], pivot) < 0) && (i < right)) i++; 
      while ((comparer.Compare(pivot, data[j]) < 0) && (j > left)) j--; 
      if (i <= j) 
      { 
       temp = data[i]; 
       data[i] = data[j]; 
       data[j] = temp; 
       i++; 
       j--; 
      } 
     } while (i <= j); 
     if (left < j) Quick_Sort(data, left, j, comparer); 
     if (i < right) Quick_Sort(data, i, right, comparer); 
    } 

    } 

    } 

所以在用户上面给出要分类为输入数字,然后选择如何排序应该怎么办?