[알고리즘] log(N^2)의 정렬, #버블정렬 #bubbleSort

2023. 3. 28. 01:30_Study/Algorithm

728x90

 

 

O(n2)의 시간 복잡도를 가지는 정렬 알고리즘


목차

1. 버블 정렬(Bubble sort)

2. 선택 정렬(Selection Sort)

3. 삽입 정렬(Insertion Sort)

4. 쉘 정렬 (Shell Sort)


 

wikipedia/버블정렬

 

 

정렬은 데이터를 정해진 기준에 따라 배치해 의미 있는 구조로 재설정하는 것을 말한다.

 

def bubbleSort(x):
	length = len(x)-1
	for i in range(length):
		for j in range(length-i):
			if x[j] > x[j+1]:
				x[j], x[j+1] = x[j+1], x[j]
	return x

 

 


 

1. 버블 정렬 (bubble sort)

- 간단하게 구현할 수 있다.

- 속도가 느리다.

- 이웃하는 두 거품을 크기순으로 swap 한다고 생각하면 된다. swap이 발생하지 않았다면 모두 정렬

- 거의 모든 상황에서 최악의 성능을 보여준다.

- 가장 손쉽게 구현하고 만들기가 쉽지만 알고리즘 적에서 대단히 비효율적이라 교육용으로 사용된다.

 

https://panthema.net/2013/sound-of-sorting/

 

The Sound of Sorting - "Audibilization" and Visualization of Sorting Algorithms - panthema.net

The Sound of Sorting - "Audibilization" and Visualization of Sorting Algorithms TalkBox macino: You could do gravity sorting. Piotr: MSD radix sort is wrong for some sizes with input n-2 equal.Binary insertion sort over-inserts the equal elements, making n

panthema.net

 

 

약간 정렬된 경우 오히려 성능이 빠르다.

 

1) Random 인 경우                    2) 오름차순인경우    

오름차순인경우 이미 정렬한 알고리즘을 확인한다고 계속 반복한다.

 

 

    3) 내림차순인경우             4) 같은 값이 많은경우  (아......) 

 

 

 

 

 

 

파생으로 칵테일 정렬(양방향 거품정렬)이 있다.

By Simpsons contributor - 자작, CC BY-SA 3.0, https://commons.wikimedia.org/w/index.php?curid=14828123

 

최악 시간복잡도 O(n2) 비교, O(n2) 교환 : 반대로 되어있는 경

최선 시간복잡도 O(n) 비교, O(1) 교환 : 이미 정렬된 경우

평균 시간복잡도  O(n2) 비교, O(n2) 교환

공간복잡도 : O(1) 보조

 

슈도코드

for i 0~N-1만큼 반복:

    for j 0~ N-1-i만큼 반복:

        현재 A리스트의 값보다 1칸 오른쪽 리스트의 값이 더 작으면 두 수를 바꾼다.

 

 

 


 

 

백준 2750번 수 정렬하기로 과정을 알아보자.

 

Tip : N의 최대 범위가 1000으로 매우 작기 때문에 버블 정렬 알고리즘을 이용해도 문제 해결 가능

 

 

빨간색 : swap 파란색: no swap 보라색 : 정렬데이터

1번째 루프

5 2 3 4 1
2 5 3 4 1
2 3 5 4 1
2 3 4 5 1
2 3 4 1 5

 

2번째 루프

2 3 4 1 5
2 3 4 1 5
2 3 1 4 5

 

3번째 루프

2 3 1 4 5
2 1 3 4 5

 

4번째 루프

1 2 3 4 5

 

 

 

디버깅 shift+F9

F8 한줄씩 실행

N = int(input())

lists = []
for i in range(N):
    lists.append(int(input()))

def bubbleSort(lists):
    for i in range(len(lists)):
        for j in range(len(lists)-1-i):
            if (lists[j]>lists[j+1]):
                lists[j],lists[j+1] = lists[j+1],lists[j]

    print(lists)

bubbleSort(lists)

 

 

 


 

백준 1377번 수 정렬하기로 과정을 알아보자.

http://acmicpc.net/problem/1377

 

 

위 코드를 확인하면 일종의 flag함수로 swap이 작동하면 change가 True로 변경된다.

즉 change가 false 일때, 정렬이 종료되었을 때를 cout(씨아웃) 으로 출력한다.

 

얼마만에 정렬이 종료될 수 있을까?

 

다만 이 문제는 N의 최대범위가 500000이기 때문에 bubbleSort를 사용하면 시간이 초과될 수 있다.

index를 고려하여 문제를 푸는 방법을 적용하면

 

방법이 가능한 이유는 결괏값을 분석하면 -인 경우는 뒤로 밀린 경우. +인 경우는 수가 작아 앞으로 정렬된 경우로 한 번 swap 일 때마다 앞으로 한 칸 가므로 1씩 늘어난다.

 

따라서 마지막 정렬까지 더하여 2+1 3인 경우로 생각한다.

 

 

import sys

def main():
    input = sys.stdin.readline
    N = int(input())

    lists = []
    lists3 = []
    for i in range(N):
        lists.append((int(input()),i))

    max = 0
    lists = sorted(lists)

    # list의 변경을 확인
    for i in range(N):
        if max < lists[i][1] - i:
            max = lists[i][1] - i


    print(max+1)

main()

 

 

http://boj.kr/d4f7238075b147ce8023c98244fbb81c

 

공유 소스 보기

 

www.acmicpc.net

 

 

참고자료 : Do it! 코딩테스트 - 기초편