ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [내가 몰라서 정리하는 알고리즘] 2. 버블정렬
    알고리즘은 어렵따. 2019. 7. 24. 02:41

    버블정렬


    (본 공부는 전부 자바를 기반으로 합니다.)

     

    옆에 있는 값과 비교해서 더 작은 값을 앞으로 보낸다.

    아주 간단하고 직관적이지만 가장 효율성이 떨어지는 알고리즘이다.

    0부터 시작하여 왼쪽의 값이 오른쪽 값보다 크다면 두 수의 자리를 바꿔준다.

    버블정렬은 한 턴이 끝날때마다 가장 큰 값이 맨 뒤로 이동 된다.

    그 후에 맨 뒤의 인덱스를 제외하고 맨 처음부터 맨 뒤의 앞 인덱스까지만 비교하여 정렬을 수행한다.

    이렇게 정렬을 반복하면 반복할 때마다 집합의 크기가 1씩 줄어든다.

     

     

     

    (선택정렬과 같은 예제를 가지고 왔다.)

    Q) 1 10 5 8 7 6 4 3 2 9

    [0] [1] [2] [3] [4] [5] [6] [7] [8] [9]

     

     

    A)

    1턴 : [0]부터 [9]까지 왼쪽의 값과 오른쪽의 값을 비교해가면서 바꿔준다.

    1턴 - 1 ) 1 10 5 8 7 6 4 3 2 9

    1턴 - 2 ) 1 5 10 8 7 6 4 3 2 9

    1턴 - 3 ) 1 5 8 10 7 6 4 3 2 9

    1턴 - 4 ) 1 5 8 7 10 6 4 3 2 9

    1턴 - 5 ) 1 5 8 7 6 10 4 3 2 9

    1턴 - 6 ) 1 5 8 7 6 4 10 3 2 9

    1턴 - 7 ) 1 5 8 7 6 4 3 10 2 9

    1턴 - 8 ) 1 5 8 7 6 4 3 2 10 9

    1턴 - 9 ) 1 5 8 7 6 4 3 2 9 10

     

    턴을 한 번 마무리 짓게 되면 위와 같이 가장 큰 10이 맨 뒤로 이동했음을 알 수 있다.

    이런 식으로 턴을 반복한다 !

    .

    .

    .

    반복하면 총 결과는 1 2 3 4 5 6 7 8 9 10 이 된다.

     

     

     

    1턴에서는 10번 비교연산을 수행하고, 2턴에서는 맨 뒤 인덱스를 제외하여 9번의 비교 연산을 수행한다.

    3턴에서는 맨 뒤 인덱스와 그 앞 인덱스를 제외하여 8번의 비교 연산을 수행하여

    이렇게 반복하여 연산을 수행하게 되면 총 연산 횟수는 다음과 같다.

     

    10 + 9 + 8 + 7 + ... + 1

     

    총 비교 연산의 횟수는 선택정렬과 같은 결과가 나온다.

     

     

    N * (N+1) / 2

     

     

    그래서 결과적으로 버블정렬의 시간복잡도 또한 선택정렬과 같은 O(N^2) 을 갖는다는 것을 알 수 있다.

     

    버블정렬의 시간복잡도는 선택정렬의 시간복잡도와 같지만 선택정렬보다는 속도가 느리다.

    선택정렬은 가장 작은 값을 선택하여 맨 앞으로 보내주는 방법으로 수행되지만 버블정렬은 계속해서 옆의 값과 비교하여 위치를 바꿔주는 방법으로 수행되기 때문에 매번 교체를 해줘야한다.

    그렇기에 선택정렬보다 훨씬 비효율적인 알고리즘이라고 할 수 있다 ..!

     

     

     

    public class BubbleSort {
    	public static void main(String args[]) {
    		int i, j, temp;
    		//int min; //최소값을 저장할 필요가 없다.
    		int array[] = {1, 10, 5, 8, 7, 6, 4, 3, 2, 9};
    		for(i=0;i<10;i++) {
    			for(j=0;j<9-i;j++) {
    				//버블 정렬은 한 턴이 끝날때마다 맨 뒤에 있는 값은 비교하지 않기 때문에 범위는 9-i로 해준다.
    				if(array[j] > array[j+1]) { //왼쪽의 값이 오른쪽 값보다 크다면
    					temp = array[j];
    					array[j] = array[j+1];
    					array[j+1] = temp;
    					//두 수의 자리를 바꿔준다.
    				}
    			}
    		}
    		
    		for(i=0;i<10;i++) {
    			System.out.print(array[i]+" ");
    		}
    	}
    }
    

     


     

    버블정렬 또한 쉬운 문제에 적용을 해보자!

    문제 출처 : JUNGOL (정보 올림피아드 & 알고리즘) http://www.jungol.co.kr/ 1157 : 버블정렬 문제

     

     

    import java.util.*;
    
    public class prac_1157 {
    	public static void main(String args[]) {
    		Scanner s = new Scanner(System.in);
    		int n = s.nextInt();
    		int array[] = new int[n];
    		int i,j,temp;
    		for(i=0;i<n;i++) {
    			array[i] = s.nextInt();
    		}
    		for(i=0;i<n;i++) {
    			for(j=1;j<n-i;j++) {
    				if(array[j-1] > array[j]) {
    					temp = array[j-1];
    					array[j-1] = array[j];
    					array[j] = temp;
    				}
    			}
    			for(int x=0;x<n;x++) {
    				if(i != n-1) {
    					System.out.print(array[x]+" ");
    				}
    			}
    			System.out.println();
    		}
    	}
    }
    

     

    참고로 덧붙이자면 위의 예제를 활용하여 코드를 짰을 때에는 0부터 시작하여 9-i 까지만 for문을 실행하여

    왼쪽(j)의 값을 기준으로 오른쪽(j+1)의 있는 값을 비교하는 식으로 밑의 문제를 풀었을 때

    배열의 인덱스를 초과하는 문제가 발생한다.

    그렇기 때문에 문제를 풀 때에는 1부터 시작하여 오른쪽(j)의 값을 기준으로

    왼쪽의 값(j-1)을 설정해주어야 문제가 풀린다.

     

     

    더 자세한 코드는 https://github.com/suhyeong (Simple Mars) 을 참고하세요.

    댓글