简体   繁体   中英

How to fix sort in ascending and descending order?

I have this error that I cannot get the selection sort into the correct ascending and descending order. I have tried every possible solution to fix this, but I cannot come up with anything else. If anyone would be willing to help me solve this, I would be very appreciated.

Error Example -

  • Bruce Wayne
  • Clark Kent
  • Ronald Raymond
  • Dinah Lance
  • Arthur Curry
  • Shayera Hol

How I want it to be -

  • Arthur Curry
  • Bruce Wayne
  • Clark Kent
  • Dinah Lance
  • Ronald Raymond
  • Shayera Hol

The sorting method

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

You're trying to implement the bubble sort algorithm, but you're iterating over the array incorrectly. First, change the inner for loop to be:

for (int j = 0; j < size - 1; j++)

Then change the if block to be:

if (switchval)
{
    Employee temp;
    temp = emp[j];
    emp[j] = emp[j+1];
    emp[j+1] = temp;
}

As you want to do this based on j , not i (as i serves to iterate all of the elements, and not part of the sorting itself).

To extend on @Hayden's answer (and on my comment to it): you should replace all references of i in your switchVal if-statement block to j and j+1 , respectfully;


By defining j with i in the declaration part of your for-loop, it seems as though you were associating i to j in an attempt to do an optimized Bubble Sort; That is, you were attempting to avoid redundant comparisons.

you should instead use i in deriving the value to compare against j in the conditional part of the for-loop (ie the max ):

for (var j = 0; j < size - 1 - i; j++)

With each complete j iteration loop occurrence, the element emp[(size - 1 - i) - 1] is going to be in it's correct, sorted index. Any redundant comparisons would be skipped as it relates to that element.

Additionally, you should include a check on whether swaps have occurred in each complete j iteration loop to handle scenarios where a list is already sorted.


In this following code section, I've defined Employee[] employees . I'll demonstrate using IOrderedEnumerable<T>.OrderBy<T, TKey>(Func<T, TKey>) to initially sort - and assign the result to employeesSortedByNameDesc . I am then going to reverse that array and assign it to variable reverseEmployees ; Finally, I'll use each Employee[] variable with the changed Sort method.

Overview and considerations:

  • Sort() on the employees
  • Sort() on the employeesSortedByNameDesc
    • no swapping should occur
    • minimum iterations
  • Sort() on the reversedEmployees
    • each iteration of j will have a swap
    • each complete j iteration will result in one item being sorted\\shifted to the end of the array;
    • maximum iterations

Employee Type

public class Employee
{
    internal string FirstName { get; set; }
    internal string LastName { get; set; }

    public string GetName() => $"{FirstName} {LastName}".Trim();

}

Sort() method (with hasSwapOccurred check-conditional 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("");
}

Program

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

Console.Write Output (it's commented out in sample code above)

排序测试的屏幕截图

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