알고리즘
[알고리즘] 정렬 정리
j9972
2022. 9. 16. 15:01
728x90
정렬 → 이보다 표준 정렬 라이브러리 사용 ( sort() )
1. 선택정렬 - 가장 작은 데이터를 선택해 맨앞의 데이터와 바꾸는 것을 반복
- 탐색 범위는 반복할때마다 줄어듬 ( 2중 for문 ) → 시간 복잡도 O(N^2)
array = [7,5,9,0,1,3,6,2,4,8]
for i in range(len(array)):
# i는 가장 작은 idx-> 맨 앞으로 보낼 것
min_idx = i # 가장 작은 워소 = i, i의 idx의미
for j in range(i+1, len(array)):
if array[min_idx] > array[j]:
min_idx = j
array[i],array[min_idx] = array[min_idx],array[i]
print(array)
2. 삽입정렬 - 데이터를 골라 적절할 위치에 삽입
- 시간 복잡도 O(N^2) , 최선의 경우 O(N) - 이미 오름차순이 되어 있을때
array = [7,5,9,0,1,3,6,2,4,8]
# 2번째 데이터부터 확인
for i in range(1,len(array)):
for j in range(i,0,-1): # idx = i ~ 1까지 1씩 감소하며 반복
#j는 삽입하고자 하는 원소
if array[j] < array[j-1]: # 한칸씩 왼쪽으로 이동
array[i],array[j-1] = array[j-1],array[i]
else: # 자기보다 작은데이터 만나면 그 위치에서 멈춤
break
print(array)
3. 퀵 정렬 - 기준 데이터를 정하고, 그 기준보다 큰 데이터와 작은 데이터 위치 교환
- 시간 복잡도 O(NlogN), 최악 O(N^2)
- 대부분에 적합함
- 첫번째 데이터를 기준 데이터를 pivot 값으로 분할한다
- 재귀적이며, 수행을 반복할수록 범위가 줄어든다.
- 분할을 할수록 절반으로 범위가 줄어든다
# way1) splicing과 컴프리헨션없는 버전
array = [7,5,9,0,1,3,6,2,4,8]
def quick_sort(array, start, end):
if start >= end: # 원소가 1개면 종료
return
pivot = start
left = start + 1
right = end
while(left <= right):
# 피봇보다 큰 데이터를 찾을때까지 반복 = 선형 탐색
while(left <= end and array[left] <= array[pivot]):
left += 1
# 피봇보다 작은 데이터를 찾을때까지 반복 = 선형 탐색
while(right > start and array[right] = array[pivot]):
right -= 1
if(left > right): # 크고 작은 데이터의 위치가 엇갈리면 작은 데이터와 피봇 교체
array[right], array[pivot] = array[pivot], array[right]
else:
array[left], array[right] = array[right], array[left]
quick_sort(array, start, right-1 )
quick_sort(array, right + 1, end )
quick_sort(array,0,len(array)-1)
print(array)
# way2 )splicing & 컴프리헨션 있음
array = [7,5,9,0,1,3,6,2,4,8]
def quick_sort(array):
#리스트가 1개 이하 원소
if len(array) <= 1:
return array
pivot = array[0]
tail = array[1:] #피벗을 제외한 리스트
left_side = [ x for x in tail if x <= pivot ] # 분할 왼쪽
right_side = [ x for x in tail if x > pivot ] # 분할 오른쪽
return quick_sort(left_side) + [pivot] + quick_sort(right_side)w
print(quick_sort(array))
4. 계수 정렬 → 동일한 값이 여러개 등장시 효과적이다
- 특정 조건 부합시 매우 빠르게 동작
- 데이터 크기 범위가 제한되어, 정수형태로 표현 가능할때 사용
- 데이터 개수 N, 최댓값 K → O(N+K)
- 각 데이터가 몇개 있는지 체크 → idx로 count 증가
array =[7,5,9,0,3,1,6,2,9,1,4,8,0,5,2]
count = [0] * (max(array)+1) # 0~9의 숫자이므로 10개의 박스 필요
for i in range(len(array)):
count[array[i]] += i # 각 데이터의 해당 idx 증가 -> O(N)
# 1씩 증가
for i in range(len(count)): # O(N+K) , 리스트에 기록된 정렬 정보 확인
for j in range(count[i]):
print(i, end=' ')
문제1) 두 배열의 원소 교체
수행과정
- 두배열 A,B가 N개의 원소로 존재
- 두배열의 원소를 교체후, A의 원소 합을 최댓값 만들기
idea
- A의 가장 작은 원소랑 B의 가장 큰 원소를 교체
n,k = map(int,input().split())
a = list(map(int,input().split()))
b = list(map(int,input().split()))
a.sort()
b.sort(reverse=True)
for i in range(k):
if a[i] < b[i]:
a[i], b[i] = b[i], a[i]
else:
break
print(sum(a))