선택 정렬 Java 및 분석

Aug 26 2020

Java로 선택 정렬 코드를 작성했습니다. 나는 그것의 매우 기본적인 알고리즘을 알고 있지만, 배우고 있기 때문에 코드의 품질에 대한 당신의 의견을 원했습니다. 코드를보십시오 : 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();
}

}

또한 분석에 대해서는 선택이 O (n2)이므로 중첩 for 루프를 사용하고 있기 때문입니다. 코드의 복잡성에 대해 알려주는 도구가 있습니까? 미리 감사 드리며 매우 순진한 경우 잠시 기다려주십시오.

답변

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

수정자가 없으면 멤버와 함수는 package-private입니다. 즉, 동일한 패키지에서 액세스 할 수 있지만 클래스를 확장하는 인스턴스로는 액세스 할 수 없습니다. 실제로 객체 지향 관점에서 볼 때 매우 이상한 일입니다. 만들 private거나 확장 클래스가 액세스 할 수 있어야하는 경우 protected.

생성자도 마찬가지입니다.


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

배열 대신 List/ ArrayList를 사용할 수 있습니다. 즉 , 미리 개수를 지정하지 않고도 사용자로부터 원하는만큼의 숫자를받을 수 있습니다. 빈 입력을 사용하여 목록의 끝을 선언 할 수 있습니다. 그러나 이것은 Integer대신 사용해야하는 단점이 int있으므로 무엇이 더 좋은지 말하기가 다소 어렵습니다. 또한 빈 입력을 감지하면에서 수동으로 변환하여 Scanner사용할 필요가 있으므로 에서 쉽게 사용할 수 있다는 단점도 있습니다 .nextLineint

List어레이를 동적으로 늘려서 에뮬레이션 할 수도 있습니다 . 모든 항목에 대해 수행하면이 사용 사례에서 성능이 중요하지 않거나 필요할 때 크기를 두 배로 늘릴 수 있습니다.


this.arrayToBeSorted=new int[total];

this예를 들어 생성자에서와 같이 동일한 범위에 동일한 이름을 가진 변수가있는 경우 에만 수정자가 필요합니다 .

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

this필요하지 않은 경우 생략 하는 것이 일반적 입니다. 인스턴스, 정적 또는 로컬 변수가 사용되는지 여부가 헷갈리는 상황에 처한 경우 어쨌든 거기에서 뭔가 잘못했습니다.


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

저는 루프의 변수에 "실제"이름을 사용하는 것에 대해 매우 끈질긴 옹호자입니다.

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

public void Sort() {

Java 명명 규칙은 메소드 / 함수가 lowerCamelCase이어야한다고 명시합니다.


int minIndex,min;

개인적으로 같은 줄에 여러 변수를 선언하는 것을 피하고 싶습니다. 선언을 놓치기 쉽습니다.


boolean swapRequired=false;

변수에 대한 훌륭한 이름의 좋은 예입니다. 감사합니다!


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

불행히도 이는 변수에 대한 잘못된 이름입니다. 치수 작업시 "x", "y"및 "z"만 사용하십시오. 여기서 "값"또는 "숫자"는 훌륭한 이름입니다.


전반적으로 유효 해 보입니다. 그래도 기능을 테스트하기 위해 실행하지는 않았습니다. 변경해야 할 것은 생성자에 논리가 있다는 것입니다. 아무도 생성자가 로직으로 채워질 것을 기대하지 않습니다. 로직의 의도를 볼 수 없기 때문입니다. 그들은 가능한 한 아무것도하지 않아야합니다. 즉, 논리 sortmain. 분류기는 입력에 전혀 관심이 없어야하며, 이상적으로는 값 정렬에만 관심을 가져야하며 다른 클래스 ( InputReader?)는 입력에 관심을 가져야합니다. 그래서 당신이 할 수있는 것은 다음과 같습니다.

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

또한 상태 Sorter를 전혀 유지할 필요가 없다는 장점이 있으므로 기본적으로 스레드로부터 안전합니다.