0

I am trying to sort an object array by the names that are inside of the array.

grades[].name

I am using an insertion method with lexicographic sorting using compareTo and it is sort of working so I know I am using the compareTo correctly but not all the name is being moved correctly and I am not sure if it is my understanding of the way lexicographic works or if my loop is causing the issue. I know lexicographic compares each letter by itself to determine the place. I originally thought it just gave the string a numeric value and was looking for a way to find that but I don't think that was the case. I have looked at the other questions in regards to how this sorting works but it doesn't seem to shed any light on my issue. I would like to know if my issues is the loop, my understanding of the sorting method or something else cause this output issue.

I have 3 classes. The object calling the .insert method is a reference to class that contains my actually array so that the array can remain private.

   `GradeArray gradeArr = new GradeArray();

    gradeArr.insert("Evans", 78, courseID);
    gradeArr.insert("Smith", 77, courseID);
    gradeArr.insert("Yee", 83, courseID);
    gradeArr.insert("Adams", 63, courseID);
    gradeArr.insert("Hashimoto", 91, courseID);
    gradeArr.insert("Stimson", 89, courseID);
    gradeArr.insert("Velasquez", 72, courseID);
    gradeArr.insert("Lamarque", 74, courseID);
    gradeArr.insert("Vang", 52, courseID);
    gradeArr.insert("Creswell", 88, courseID);`

this is to make the entries in the array.

Here is my sorting loop.

`  public String reportgrades() //this is grade sorted by name 
    {
        String output = "Sorted by name ";
        int in, out;
        StudentGrade temp; //this is to hold the orginal variable. 
        //for the first letter cycle
        for (out = 1; out < nElems; out++) {
            temp = grades[out];
            in = out;
            while (in > 0 && 0 < (grades[in - 1].name.compareTo(grades[in].name))) {
                grades[in] = grades[in - 1];
                in--;
            }
            grades[in] = temp;
        }
        for (int j = 0; j < nElems; j++) {
            output += grades[j].name + ", ";
        }
        return output;
    }`

The output this is creating is Sorted by name Evans, Smith, Adams, Hashimoto, Stimson, Velasquez, Lamarque, Vang, Creswell, Yee,

I am confused as to why Evans and Smith are before Adams. I have tried to look at the docs for the way compareTo works but I didn't seem to see anything that would give me any information on it.

Grimmjow56
  • 19
  • 1
  • 1
  • 9
  • 3
    Is this some kind of homework where the main challenge is to write your own sort algorithm? Or why don't you use the built-in sort? – Ringo Store Feb 03 '18 at 21:44
  • 1
    Perhaps SO is self-motivated and wants to write a sort. It could happen. – nicomp Feb 03 '18 at 21:45
  • 1
    In all seriousness, this is a job for SO and his/her debugger. Step through it. – nicomp Feb 03 '18 at 21:48
  • the while loop is interrupted as soon as you find a 'greater' name, "Adams" get changed with "Yee".which is always 'greater' . So the while loop will always be interrupted after reaching/moving "Yee". – user85421 Feb 03 '18 at 22:37

4 Answers4

0

First, add all names into list, then sort:

Collections.sort(list);      
סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
kamoloff
  • 118
  • 1
  • 9
0

Your use of compareTo is fine, but you aren't comparing the right elements for insert sort. You need to compare the element that was at out with each earlier element. But after the first step in your loop, you are instead only comparing elements from earlier that out against each other.

You can either change the while loop to compare against temp:

while (in > 0 && 0 < (grades[in - 1].name.compareTo(temp.name))) {

or keep that while, but change the loop to swap the elements in the array rather than just shift them to the right:

    for (out = 1; out < nElems; out++) {
        in = out;
        while (in > 0 && 0 < (grades[in - 1].name.compareTo(grades[in].name))) {
            // swap grades at in-1 and in
            StudentGrade temp = grades[in];
            grades[in] = grades[in - 1];
            grades[in - 1] = temp;
            in--;
        }
    }
0

There is a problem with the algorithm when you shift the values. You need to put grades[in-1] = temp; inside your while statement in order to the shift work. I did not use a GradeStudent just a String but you can adapt. The grades array was just for an example.

public static String reportgrades() //this is grade sorted by name 
    {

    String[] grades = {"Evans", "Smith", "Adams", "Hashimoto", 
    "Stimson", "Velasquez", "Lamarque", "Vang", "Creswell", "Yee"};
    String output = "Sorted by name ";
    int in, out;
    String temp; //this is to hold the orginal variable. 
    //for the first letter cycle
    long nElems = grades.length; 
    for (out = 1; out < nElems; out++) {
        in = out;
        while (in > 0 &&  0 < (grades[in - 1].compareTo(grades[in]))) {
            temp = grades[in];
            grades[in] = grades[in-1];
            grades[in-1] = temp;
            in--;
        }    
    }
    for (int j = 0; j < nElems; j++) {
         output += grades[j] + ", ";
    }
    return output;
}
vladwoguer
  • 951
  • 1
  • 14
  • 28
  • Note that if you need to consider "Adam" and "adam" the same while ordering you will need to add a uppercase or lowercase. – vladwoguer Feb 03 '18 at 23:12
0

I followed vladwoguer answered and moved the grades[in-1] = temp; into my while loop. I didn't realize I wasn't actually moving the variable I wanted. I thought everything had to move everything over before I reinserted the original name.

Grimmjow56
  • 19
  • 1
  • 1
  • 9