Auswahl Java und Analyse sortieren

Aug 26 2020

Ich habe einen Auswahlsortiercode in Java geschrieben. Ich kenne seinen sehr elementaren Algorithmus, aber da ich lerne, wollte ich Ihre Eingabe über die Qualität des Codes. Bitte schauen Sie sich den Code an: package selection_sort;

import java.util.Scanner;

public class SelectionSort {

int [] arrayToBeSorted;
Scanner scan=new Scanner(System.in);


SelectionSort(){
    System.out.println("Enter the number of elements");
    int total=scan.nextInt();
    this.arrayToBeSorted=new int[total];
    for(int i=0;i<total;i++) {
        System.out.println("Enter the "+i+" number of elements");
        this.arrayToBeSorted[i]=scan.nextInt();
    }
    
}

public void Sort() {
    int minIndex,min;
    boolean swapRequired=false;
    for(int i=0;i<arrayToBeSorted.length;i++) {
        minIndex=i;
        min=this.arrayToBeSorted[i];
        for(int j=i+1;j<this.arrayToBeSorted.length;j++) {
            if(this.arrayToBeSorted[j]<min) {
                min=this.arrayToBeSorted[j];
                minIndex=j;
                swapRequired=true;
            }
        }
        if(swapRequired) {
            swap(i,minIndex);
        }
                    
    }
    
    for(int x:this.arrayToBeSorted) {
        System.out.print(x+" ");
    }
        
    }

public void swap(int i,int j) {
    
    //System.out.println("swap called, pos="+i+"and minindex="+j);
    int temp=this.arrayToBeSorted[i];
    this.arrayToBeSorted[i]=this.arrayToBeSorted[j];
    this.arrayToBeSorted[j]=temp;
    
    //System.out.println("------------");
    
}
public static void main(String[] args) {
    SelectionSort s=new SelectionSort();
    s.Sort();
}

}

Auch über die Analyse, da die Auswahl O (n2) ist, liegt es daran, dass ich eine verschachtelte for-Schleife verwende. Gibt es ein Tool, das uns über die Komplexität des Codes informiert? Vielen Dank im Voraus und bitte haben Sie etwas Geduld, wenn es sehr naiv ist

Antworten

1 Bobby Aug 26 2020 at 23:37
int [] arrayToBeSorted;
Scanner scan=new Scanner(System.in);

Ohne Modifikator sind Mitglieder und Funktionen package-private. Dies bedeutet, dass auf sie über dasselbe Paket zugegriffen werden kann, jedoch nicht über Instanzen, die die Klasse erweitern. Das ist eigentlich eine äußerst seltsame Sache, wenn man es aus objektorientierter Sicht betrachtet. Sie möchten sie entweder privateerstellen oder wenn erweiterte Klassen auf sie zugreifen können sollen protected.

Gleiches gilt für den Konstruktor.


    System.out.println("Enter the number of elements");
    int total=scan.nextInt();
    this.arrayToBeSorted=new int[total];

Sie können ein List/ ArrayListanstelle eines Arrays verwenden, was bedeutet, dass Sie von den Benutzern so viele Nummern erhalten können, wie sie möchten, ohne zuvor die Anzahl angeben zu müssen. Eine leere Eingabe kann verwendet werden, um das Ende der Liste zu deklarieren. Dies hat jedoch den Nachteil, dass Sie Integerstattdessen verwenden müssen int, sodass es schwierig ist zu sagen, was besser ist. Es hat auch den Nachteil, dass das Erkennen einer leeren Eingabe so leicht verfügbar ist Scanner, wie Sie es nextLinefür die manuelle Konvertierung in benötigen würden int.

Sie können a auch emulieren, Listindem Sie das Array dynamisch vergrößern. Entweder indem Sie dies für jeden Artikel tun, spielt die Leistung in diesem Anwendungsfall keine Rolle, oder indem Sie die Größe bei Bedarf verdoppeln.


this.arrayToBeSorted=new int[total];

Sie benötigen den thisModifikator nur, wenn Sie eine Variable mit demselben Namen im selben Bereich haben, z. B. in einem Konstruktor:

public ValueContainer(int value) {
    this.value = value;
}

Es ist üblich, wegzulassen, thiswenn es nicht benötigt wird. Wenn Sie sich jemals in der Situation befinden, dass es verwirrend ist, ob eine Instanz, eine statische oder eine lokale Variable verwendet wird, haben Sie dort sowieso etwas falsch gemacht.


for(int i=0;i<total;i++) {

Ich bin ein sehr hartnäckiger Verfechter der Verwendung von "echten" Namen für Variablen in Schleifen.

for (int counter = 0; counter < total; counter++) {
// or
for (int index = 0; index < total; index++) {

public void Sort() {

Die Java-Namenskonventionen legen fest, dass Methoden / Funktionen lowerCamelCase sein sollten.


int minIndex,min;

Persönlich würde ich vermeiden, mehrere Variablen in derselben Zeile zu deklarieren. Es macht es leicht, eine Erklärung zu verpassen.


boolean swapRequired=false;

Das ist ein großartiges Beispiel für einen großartigen Namen für eine Variable, danke!


    for(int x:this.arrayToBeSorted) {
        System.out.print(x+" ");
    }

Das ist leider ein schlechter Name für eine Variable. Verwenden Sie nur "x", "y" und "z", wenn Sie mit Bemaßungen arbeiten. "Wert" oder "Zahl" wäre hier ein großartiger Name.


Insgesamt sieht es gültig aus. Ich habe es jedoch nicht ausgeführt, um die Funktionalität zu testen. Was Sie ändern sollten, ist, dass Sie Logik im Konstruktor haben. Niemand erwartet, dass Konstruktoren mit Logik gefüllt sind, weil Sie die Absicht der Logik von ihnen nicht erkennen können. Sie sollten so wenig wie möglich tun. Das bedeutet, dass Sie die Logik in sortoder, noch besser, in verschieben sollten main. Ihr Sortierer sollte sich überhaupt nicht mit Eingaben befassen, er sollte sich im Idealfall nur mit dem Sortieren von Werten befassen, und eine andere Klasse ( InputReader?) Sollte sich mit dem Abrufen der Eingaben befassen. Was Sie also tun könnten, ist ungefähr so:

public static final void main(String[] args) {
    InputReader inputReader = new InputReader();
    
    int[] values = inputReader.readValues();
    
    Sorter sorter = new Sorter();
    sorter.sort(value);
    
    // TODO Print sorted output.
}

Das hat auch den Vorteil, dass Sie den Status überhaupt nicht halten müssen Sorter, was ihn standardmäßig threadsicher machen würde.