본문 바로가기
자료구조및알고리즘

(Python)힙 정렬

by windy7271 2022. 6. 21.
728x90
반응형

 

힙 정렬은 힙 트리 구조를 이용하는 정렬 방법이다.

 

이진트리 / 힙 

 

이진트리란 컴퓨터 안에서 데이터를 표현할때 데이터를 노드에 담아 노드를 두개씩 이어 붙이는 구조

이진트리는 모든 노드의 자식 노드가 2개이하인 노드이다.

맨 위는 루트 맨 아래는 리프

 

완전 이진 트리:  데이터가 루트노드로 시작해 자식노드가 왼쪽,오른쪽 으로 차근차근 들어가는 구조의 이진 트리이다.

중간에 빈 값 없이 꽉 차 있다.

 

힙 : 최솟값이나 최댓값을 빠르게 찾아내기 위해 완전 이진 트리를 기반으로 하는 트리, 최대힙은 부모 노드가, 자식 노드 보다 큰 힙이다.

- 힙은 중복값을 허용한다. 힙은 최댓값 또는 최솟값을 쉽게 뽑기 위한 자료구조 이기 때문

 

 

만약 자식노드가 부모노드보다 큰 경우 힙 정렬을 하는데 이것을 힙 생성 알고리즘이라고 한다.

정렬을 한 후에도 여전히 자식이 존재하는 경우 또 자식 중에서 더 큰 자식노드와 자신의 위치를 바꿔야한다.

 

삽입 또는 삭제가 일어나게 되면 경우에 따라 최대힙의 조건이 깨질 수 있다. >> 이럴때 조건을 만족하게 

노드들의 위치를 바꿔가며 힙을 재구조화(Heapify) 해준다.

 

힙 생성 알고리즘의(heapify) 시간 복잡도: 한번 수행될때 수행시간은 트리의 높이와 같기때문에 O(logN) 이다.

힙을 구성하는 시간 복잡도: 비어있는 힙에 주어진 n개의 요소를 차례대로 삽입연산을 해야 하므로, O(nlogN)이다.

 

코드:

array = [1, 10, 5, 8, 7, 6, 4, 3, 2, 9]
# 상향식

def heap_sort(array):
    n = len(array)
    # 전체 트리 구조를 최대 힙 구조로 바꿈
    for i in range(n):
        c = i
        while c != 0:               # c는 자식노드
            r = ( c-1 ) // 2        # r은 부모노드 의 인덱스
            if (array[r] < array[c]):   # 자식이 더크면 부모와 교환
                array[r], array[c] = array[c], array[r]
            c = r               # 자식노드에서 부모노드로 이동
            # print(array)

    # 크기를 줄여가면서 heap 구성
    for j in range(n-1, -1, -1):
        array[0] , array[j] = array[j], array[0]  # 첫 값과 맨 뒤에 있는 원소를 바꿈
        r = 0   # 루트의 위치
        c = 1   # 변수 이용
        while c < j:
            c = 2 * r +1    # 자식
            # 자식 중 더 큰 값 찾기
            if (c < j - 1) and (array[c] < array[ c+1 ]):
                c += 1
            # c 와 c+1 중 비교해서 더 큰값을 c 에 넣어주는 것
            # 범위를 벗어나지 않게 c<j-1 로 막아준것

            # 루트보다 자식이 크다면 교환
            if (c < j) and (array[r] < array[c]):
                array[r], array[c] = array[c], array[r]
            r = c
            # 다시 c 를 r로 이동시켜 재귀적으로 동
    print(array)
heap_sort(array)

 

 

 

 

 

 

 

 

 

 

반응형

댓글