무엇인가?
순서 없이 정렬된 리스트를 하나하나 비교해가며 순서대로 정렬하는 기법이다. (오름 차순으로 정렬하는걸 정리함)
공부 방법
노트에 직접 상황들을 적어가며 공부함 길이가 긴 리스트여도 흐름을 파악할때까지 리스트의 길이를 늘림
다행히 길이가 4까지만 해도 이해가 되었다.
생각한 내용 적어보기
처음 생각한대로 내용 적고 코딩한 결과
list1 = [5, 3, 4, 1, 2]
for i in range(len(list1)):
for j in range(len(list1)-1):
if list1[j] > list1[j+1]:
list1[j+1], list1[j] = list1[j], list1[j+1]
print(list1)
첫 for문에서 list1의 길이를 체크해서 그 횟수만큼 돌고 j가 포함되어있는 for문에서 리스트의 길이 -1을 하면 문제 없이 돌지 않을까? -1을 한 경우는 어짜피 정렬이고 순서대로 정렬하는 문제이면 뒤의 수(list1[j+1])
를 써야하기때문에 마지막 길이까지 갔을땐 그 뒤의 수가 없기때문이라 -1을 해줘야한다고 생각했다.
일단, 정렬은 잘 되어 결과가 문제 없이 나온다.
하지만, 과정을 보면 순회가 필요없는곳 까지 순회를 해버려서 코드의 효율성이 현저히 떨어지는걸 볼 수 있다.
# 과정
list1 = [5, 4, 3, 2]
for i in range(len(list1)): # 현재 list1의 길이는 4이다.
for j in range(len(list1)-1): # list1의 길이 4 그리고 -1 을 하면 3이다. index 0, 1, 2 이렇게 3번 순회 한다는 소리다.
# i = 0
## j = 0 / j + 1 = 1
## j = 1 / j + 1 = 2
## j = 2 / j + 1 = 3. -> list1 max 길이인 3번째 index까지 돌았다.
# i = 1
## j = 0 / j + 1 = 1
## j = 1 / j + 1 = 2
## j = 2 / j + 1 = 3. -> 이렇게 또 list1의 max 길이인 3번째 index까지 돌았다.
# 더이상 과정을 적어보지 않아도 계속 이렇게 될것이란걸 예상 할 수 있을것이다.
이렇게 효율성이 떨어지는걸 사용할 수 없으니깐 조치를 취해야한다.
그래서 내린 결론은
list1 = [5, 3, 4, 1, 2]
for i in range(len(list1)-1): # -1이 추가되었다.
for j in range(len(list1)-i-1): # -i 가 추가 되었다.
if list1[j] > list1[j+1]:
list1[j+1], list1[j] = list1[j], list1[j+1]
print(list1)
위 코드를 보면 첫번째 for문에 길이가 -1
추가 되었고 두번째 for문에 -i
가 추가되었는데
첫번째 for문에 -1을 안하고(for i in range(len(list1))
) 그냥 길이가 4인채 두번째 for문으로 넘기게 되면 길이 연산(range(len(list1)-i-1))
에서 첫번째 for문의 수가 4로 내려올때 길이 연산을 하게되면 4-4-1
이 된다.
이렇게 되면 -1인 인덱스 즉, 마지막 인덱스와 거기에 +1한 0번째 인덱스를 비교하게 된다.
물론 그렇게 비교를 할 순 있겠지만 버블 정렬 형식에 맞지 않기에 사용하지 않기로 한다. 이러한 과정을 겪었으므로 첫번째 for문에서 길이에 -1을 하게됨으로써 -1인 인덱스가 나오는 상황을 막을 수 있다.
그런데 몇가지 생각을 해보면 무조건 순서없이 정렬 되어있진 않을 것이다.
어떤건 리스트는 전부 제대로 정렬되어있다면 반복문 도는 자체가 효율성 Zero가 된다고 생각한다.
그래서 True/False를 사용해서 처음 for문을 돌았을때 swap된 상황이 있는지 없는지 판별 해주도록 한다.
def bubble_sort(array: list) -> list:
for i in range(len(array) - 1):
swap = False
for j in range(len(array) - i - 1):
if array[j] > array[j + 1]:
array[j + 1], array[j] = array[j], array[j + 1]
swap = True
if not swap:
break # 한 번 돌았는데 swap이 False일때(처음 for문을 돌았는데 변경할게 없다) 바로 모든걸 멈추고 빠져나가도록 한다.
return array
if __name__ == "__main__":
list1 = [5, 3, 4, 1, 2]
print(bubble_sort(list1))
'알고리즘' 카테고리의 다른 글
삽입정렬 -스터디- (0) | 2021.06.25 |
---|---|
선택정렬 -스터디- (0) | 2021.06.21 |
약수의 합 (0) | 2020.10.12 |
두개뽑아서 더하기 (0) | 2020.10.02 |
제일 작은 수 제거 (0) | 2020.09.06 |