0

I tried to make a quick sort function for a linked list, which can sort objects based on a given variable. But I have the problem that the outpout of the quick sort function is neither sorted nor unchanged. Instead it is completly diffrent.

I've tried to change the addfirst function and I tried to change the connect function, but it doesn't do anything.

So for Example here the console Out put of the list I wanted to sort: (Translation:"Sein name ist": "His name his") :

Sein Name ist: Haarald(Alter: 3)
Sein Name ist: Mark(Alter: 2)
Sein Name ist: Guenter(Alter: 1)
Sein Name ist: Kai(Alter: 4)

And now the console output of the list after I gave it in the quick sort Function:

Sein Name ist: Haarald(Alter: 3)
Sein Name ist: Mark(Alter: 2)
Sein Name ist: Guenter(Alter: 1)
Sein Name ist: Kai(Alter: 4)
Sein Name ist: Haarald(Alter: 3)
Sein Name ist: Guenter(Alter: 1)
Sein Name ist: Mark(Alter: 2)
Sein Name ist: Guenter(Alter: 1)

So it's strange that the output is more than the input.

And here the function`s that I used:

Quick sort function:

fun quickSort(comparator: Comparator<T>){
        if (this.size() < 2)return;

        val pivot = this.getFirst().content;     //Vergleichs Element

        val less = Liste<T>();
        val equal= Liste<T>();
        val more = Liste<T>();

        for (element in this){
            val compared = comparator.compare(pivot,element)
            when{
                compared >  0 -> less.addfirst(element);
                compared == 0 -> equal.addfirst(element);
                compared <  0 -> more.addfirst(element);
            }
        }
        less.quickSort(comparator)
        more.quickSort(comparator)

        this.first = conect(this,conect(equal,less)).first
    }

comperator:

val intComperator = Comparator<Mensch>{o1: Mensch, o2:Mensch -> when{

          o1.alter == o2.alter -> 0
          o1.alter < o2.alter -> -1
          o1.alter > o2.alter -> 1
          else -> 0
          }
           }

Helper Functions: fun getFirst():Eintrag{ return first?: throw Exception("(getFirst)No Elements in this List")}

fun conect(mainList:Liste<T>,toAdd:Liste<T>):Liste<T> {
        mainList.getLast().next = toAdd.first;
        return mainList
    }

and the last code, the implementation of the list:

class Liste<T>:Iterable<T>{
   
    class Eintrag<T>(val content:T, var next:Eintrag<T>?)

    private var first :Eintrag<T>? = null;

And here is the full code, I'm sorry, I know it's messy and I need to break the code into more than one file and something about my formatting too: https://github.com/TheDarkRiddle/Kotlin-quick-sort

  • Could you please work a little bit on the formatting of your question? It's hard enough to read through a different language, but the example output and the text mixed with the code don't make it any easier ;) – Joffrey Jun 01 '21 at 15:44
  • You should update the example so that it can be executed by others. It's hard for people to help if they cannot run your code. – Adam Millerchip Jun 02 '21 at 03:37
  • Okay, thank you for you feed back. I try to do Code completely in english next time, so that my english skills gett better to.But for now the solution of Alex.T helped me. – TheDarkRiddle Jun 02 '21 at 14:03

1 Answers1

0

If your class would implement the Comparable interface docs here and example here instead of having it as a separate value, you could use a simple quick sort implementation like this.

fun <E : Comparable<E>> List<E>.quickSort(): List<E> =
    when {
        size < 2 -> this
        else -> {
            val (l, h) = subList(1, size).partition { it < first() }
            l.quickSort() + first() + h.quickSort()
        }
    }

Alternatively, you could modify this to use your comparator val, but honestly I find this to be a bit harder to understand, and will only work for objects of type Mensch.

fun List<Mensch>.quickSort(comparator: Comparator<Mensch>): List<Mensch> =
    when {
        size < 2 -> this
        else -> {
            val (l, h) = subList(1, size).partition { intComperator.compare(it, first()) == -1 }
            l.quickSort(comparator) + first() + h.quickSort(comparator)
        }
    }

I haven't included the Liste class here in any way, since when you are debugging something, it is best to reduce the code as much as possible (that is why it is also a advice on SO to create the minimal reproducible example), and then start adding to it, then you can easily detect if your comparator is off, or if your classes are off or etc.

AlexT
  • 2,524
  • 1
  • 11
  • 23
  • Thank you for your help, even if my question wasn't well worded – TheDarkRiddle Jun 02 '21 at 14:05
  • I tried a bit,but if I am honest, i dont understand much of your function. The doc entry helped me to understand the "Comparable interface",but I dont know how to implement your example. Maybe you have another example, or another doc? – TheDarkRiddle Jun 02 '21 at 16:27
  • if you implement comparable into Mensch itself, you call the first one by doing `val list = listOf(); list.quickSort()`, replace the first part with your actual list. If you want to keep using your own `intComperator`, you do `list.quickSort(intComperator)`. – AlexT Jun 02 '21 at 17:05
  • Okay, thank you. Now it is working and I also find a way to make it work with my linked list. – TheDarkRiddle Jun 02 '21 at 19:36