본문 바로가기
프로그래밍/Baekjoon & Codeup

[Codeup] 3011번 거품정렬(Bubble Sort) 문제 풀이

by Homo_Viator 2023. 9. 7.

링크 - https://codeup.kr/problem.php?id=3011 

 

거품 정렬(Bubble Sort)

첫 줄에 데이터의 개수 n이 입력된다. (2 <= n <= 1,000) 둘째 줄에 n개의 데이터가 공백을 기준으로 입력된다.

codeup.kr

 

문제

버블 정렬이란 이웃하는 숫자들끼리 크기를 비교하여 자리를 바꾸는 정렬 기법이다.

버블 정렬은 구현이 쉬운 반면 속도가 빠른 편은 아니다.

그리고 가장 큰 단점으로 정렬이 이미 다 끝났는데도, 끝까지 대소비교를 하는 문제점이 있다.

예를 들어, 10 50 30 20 40 이 있고 오름차순으로 정렬한다면 총 4단계를 거치게되는데,

1단계 : 10 30 20 40 50

2단계 : 10 20 30 40 50  (정렬 완료)

3단계 : 10 20 30 40 50

4단계 : 10 20 30 40 50

4단계중 이미 2단계에서 정렬이 완료가 된다.

이 단계를 구하는것이 문제이다. 이 단계를 찾아 프로그램을 종료시키면 정렬속도를 향상 시킬수있다.

이 단계를 찾아 내는 프로그램을 작성하시오.

 

아이디어

버블 정렬 알고리즘의 코드를 효율적으로 짜는 것과 관련이 있습니다.

비효율적으로 작성한 버블 정렬은 이미 정렬이 끝난 상황을 구분하지 못하는데요.

위 문제의 예시처럼 2단계에 정렬이 끝났어도 4단계까지 프로그램이 실행되는 불필요한 과정을 거칠 수 있습니다.

이 비효율을 해결하는 것이 결국 이 문제를 풀 수 있는 아이디어입니다.

 

소스코드에서 정렬은 특정 조건(if문)을 만족할 때 주어진 리스트의 원소끼리 swap을 함으로써 이루어집니다.

그렇다면 이미 정렬이 되어 있어 특정 조건을 만족하지 않는다면 swap을 하지 않을 것입니다.

이를 이용하여 특정 단계에서 swap 여부를 판단해 반복문으로부터 break를 실행하고

그 상황에서의 단계를 출력하면 됩니다.

 

소스코드

 

#include <iostream>
using namespace std;
int n,inp[1001],cnt;
int main()
{
    scanf("%d", &n);
    for(int i=1;i<=n;i++) scanf("%d",&inp[i]);

    for(int i=1;i<=n;i++)
    {
        cnt=i;
        bool check=0;//swap 여부를 check이 0인지 1인지로 판단
        for(int j=2;j<=n-1;j++)
        {
            if(inp[j]<inp[j-1])
            {
                swap(inp[j-1],inp[j]);
                check=1;//check 변경
            }
        }
        if(check==0) break;//swap이 실행되지 않았다면
    }
    
    if(cnt==1) printf("1");
    else printf("%d",cnt-1);
    return 0;
}

 

728x90