我有一个错误,无法将选择排序按正确的升序和降序排列。我已经尝试了所有可能的解决方案来解决此问题,但是我无能为力。如果有人愿意帮助我解决这个问题,我将不胜感激。
错误示例-
我想要的样子-
排序方法
public static void Sort(Employee[] emp, int size, int choice) {
for (int i = 0; i < size - 1; i++) {
for (int j = i + 1; j < size - 1; j++) {
bool switchval = false;
switch (choice) {
case 1: // ascending sort by employee name
if (emp[j].GetName().CompareTo(emp[j + 1].GetName()) > 0)
switchval = true;
break;
case 2: // ascending sort by employee number
if (emp[j].GetNumber() > emp[j + 1].GetNumber())
switchval = true;
break;
case 3: // descending sort by hourly rate
if (emp[j].GetRate() < emp[j + 1].GetRate())
switchval = true;
break;
case 4: // descending sort by weekly hours
if (emp[j].GetHours() < emp[j + 1].GetHours())
switchval = true;
break;
case 5: // descending sort by gross pay
if (emp[j].GetGross() < emp[j + 1].GetGross())
switchval = true;
break;
}
if (switchval) {
Employee temp;
temp = emp[i];
emp[i] = emp[j];
emp[j] = temp;
}
}
}
}
答案 0 :(得分:3)
您正在尝试实现bubble sort
算法,但是您不正确地遍历了数组。首先,将内部for循环更改为:
for (int j = 0; j < size - 1; j++)
然后将if块更改为:
if (switchval)
{
Employee temp;
temp = emp[j];
emp[j] = emp[j+1];
emp[j+1] = temp;
}
您要基于j
而不是i
进行操作(因为i
用于迭代所有元素,而不是排序本身的一部分)。
答案 1 :(得分:0)
要扩展@Hayden的回答(以及我对此的评论):您应该将i
if语句块中的switchVal
的所有引用替换为j
和{{1 }};
通过在for循环的声明部分中将j+1
与j
一起定义,似乎您正在将i
与i
进行关联,优化的冒泡排序;也就是说,您正在尝试避免多余的比较。
您应该改用j
来获取要与for循环的条件部分(即i
)中的j
进行比较的值:
max
每次出现完整的for (var j = 0; j < size - 1 - i; j++)
迭代循环时,元素j
将位于正确的排序索引中。与该元素相关的所有多余比较都将被跳过。
此外,您应检查每个完整的emp[(size - 1 - i) - 1]
迭代循环中是否发生了交换,以处理已对列表进行排序的情况。
在下面的代码部分中,我定义了j
。我将演示如何使用Employee[] employees
进行初始排序-并将结果分配给IOrderedEnumerable<T>.OrderBy<T, TKey>(Func<T, TKey>)
。然后,我将反转该数组并将其分配给变量employeesSortedByNameDesc
;最后,我将每个reverseEmployees
变量与更改后的Employee[]
方法一起使用。
概述和注意事项:
Sort
上的Sort()
employees
上的Sort()
employeesSortedByNameDesc
上的Sort()
reversedEmployees
的每个迭代将有一个j
swap
迭代将导致一项被排序\移位到数组的末尾; j
类型Employee
public class Employee
{
internal string FirstName { get; set; }
internal string LastName { get; set; }
public string GetName() => $"{FirstName} {LastName}".Trim();
}
方法(使用Sort()
检查条件hasSwapOccurred
)break;
static void Sort(Employee[] emp, int size, int choice)
{
for (int i = 0; i < size - 1; i++)
{
bool hasSwapOccurred = false;
for (int j = 0; j < size - 1 - i; j++)
{
bool switchval = false;
switch (choice)
{
case 1: // ascending sort by employee name
if (emp[j].GetName().CompareTo(emp[j + 1].GetName()) > 0)
switchval = true;
break;
default:
break;
}
if (switchval)
{
Employee temp;
temp = emp[j];
emp[j] = emp[j + 1];
emp[j + 1] = temp;
}
//Console.WriteLine($"(switchval := {switchval}, hasSwapOccurred := {hasSwapOccurred}) => [{string.Join(",", emp.Select(e => e.GetName()).ToArray()) }]");
}
//Console.WriteLine("-----");
if (!hasSwapOccurred)
break;
}
//Console.WriteLine("");
}
static void Main(string[] args)
{
var employees = new Employee[]
{
new Employee { FirstName = "Bruce", LastName = "Wayne"},
new Employee { FirstName = "Clark", LastName = "Kent"},
new Employee { FirstName = "Ronald", LastName = "Raymond"},
new Employee { FirstName = "Dinah", LastName = "Lance"},
new Employee { FirstName = "Arthur", LastName = "Curry"},
new Employee { FirstName = "Shayera", LastName = "Hol"}
};
var employeesSortedByNameDesc = employees.OrderBy(SelectEmployeeName).ToArray();
var reversedEmployees = employeesSortedByNameDesc.Reverse().ToArray();
Sort(employees, employees.Length, 1);
Sort(employeesSortedByNameDesc, employeesSortedByNameDesc.Length, 1);
Sort(reversedEmployees, reversedEmployees.Length, 1);
string SelectEmployeeName(Employee e) => e.GetName();
}
输出(在上面的示例代码中已注释掉)