如何让我的快速排序算法同时按升序和降序对数组进行排序?
How can I make my Quick Sort Algorithm sort the arrays in both Ascending and Descending order?
目前,我的快速排序算法在情况 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);
}
添加允许更改比较结果的参数
(data[i].CompareTo(pivot) < 0)
and
(pivot.CompareTo(data[j]) < 0)
一种简单的方法:参数 descending +1/-1
并使用
data[i].CompareTo(pivot) * descending < 0
您可以更改快速排序方法以接受 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);
}
}
}
这有两个好处:
- 类型
T
不需要实现 IComparable<T>
。您可以传入一个进行比较的 IComparer<T>
对象。
- 您可以通过传入不同的自定义
IComparer<T>
对象以多种方式对相同数据进行排序。
这是许多 Linq IEnumerable 扩展所采用的方法,例如 Enumerable.OrderBy()
只是在@Matthew Watson 的回答上加了点奶油。在阅读@Illimar 的 post 之后,他想让用户选择以升序模式或降序模式对数组进行排序。我刚刚编辑了@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);
}
}
}
所以在上面,用户给出了要排序的数字作为输入,然后选择应该如何进行排序?
目前,我的快速排序算法在情况 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);
}
添加允许更改比较结果的参数
(data[i].CompareTo(pivot) < 0)
and
(pivot.CompareTo(data[j]) < 0)
一种简单的方法:参数 descending +1/-1
并使用
data[i].CompareTo(pivot) * descending < 0
您可以更改快速排序方法以接受 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);
}
}
}
这有两个好处:
- 类型
T
不需要实现IComparable<T>
。您可以传入一个进行比较的IComparer<T>
对象。 - 您可以通过传入不同的自定义
IComparer<T>
对象以多种方式对相同数据进行排序。
这是许多 Linq IEnumerable 扩展所采用的方法,例如 Enumerable.OrderBy()
只是在@Matthew Watson 的回答上加了点奶油。在阅读@Illimar 的 post 之后,他想让用户选择以升序模式或降序模式对数组进行排序。我刚刚编辑了@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);
}
}
}
所以在上面,用户给出了要排序的数字作为输入,然后选择应该如何进行排序?