[자료구조] 힙과 힙소트

2015. 6. 8. 16:39·개념/자료구조

힙

힙은 자료구조의 하나로 최대값, 최소값을 찾아내는 연산을 빠르게 하기 위해 고안된 완전이진트리를 기본으로한다.

l  최대힙 : 부모노드의 값이 자식노드보다 크다.

l  최소힙 : 자식노드의 값이 부모노드보다 크다.

부모와 자식 노드간의 대소관계만 정해지고, 자식 노드간의 대소관계는 정해지지 않는다.

 

힙정렬

힙을 구성하여 정렬을 수행하는 것을 힙정렬이라 한다.

최대힙을 이용하여 정렬을 수행하는 방법은 다음과 같다.

1. 최대힙을 구성한다.

2. 최대힙의 루트값을 배열의 맨뒤로 보내고 배열의 사이즈를 하나 줄인다.

3. 변경된 배열에 대해서 최대힙을 다시 구성한다.

4. 2 ~ 3의 과정을 배열의 길이가 1이 될때까지 반복한다.

 

소스코드[Java]

public class MaxHeapSort {

    public static void main(String[] args) {
        
        // 데이터 입력
        MaxHeap heap = new MaxHeap(10);
        heap.insert(5);
        heap.print();
        heap.insert(6);
        heap.print();
        heap.insert(2);
        heap.print();
        heap.insert(3);
        heap.print();
        heap.insert(9);
        heap.print();
        heap.insert(40);
        heap.print();
        heap.insert(33);
        heap.print();
        heap.insert(11);
        heap.print();
        heap.insert(15);
        heap.print();
        heap.insert(100);
        heap.print();
        
        // 데이터 삭제
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
//      System.out.println("remove : " + heap.remove());
//      heap.print();
        
        // 정렬후 출력
        int[] array = heap.sort();
        for (int i : array) {
            System.out.print(i);
            System.out.print(" ");
        }
    }
}

class MaxHeap {

    int capacity;
    int[] array;
    int currentLocation;

    public MaxHeap(int capacity) {
        this.capacity = capacity;
        array = new int[capacity];
    }

    public void insert(int value) {

        if (currentLocation == capacity) {
            System.out.println("heap is full");
            return;
        }

        array[currentLocation] = value;
        int parentLocation = (currentLocation - 1) / 2;

        // 데이터 추가후 힙을 재구성한다. 
        insert_sort(parentLocation, currentLocation++);
    }

    /**
     * 데이터 추가후 힙 재구성
     * 현재 노드의 값이 부모노드의 값보다 크면 변경후 재확인
     * 
     * @param parentLocation
     * @param currentLocation
     */
    private void insert_sort(int parentLocation, int currentLocation) {

        if (parentLocation >= 0 && array[parentLocation] < array[currentLocation]) {
            int temp = array[parentLocation];
            array[parentLocation] = array[currentLocation];
            array[currentLocation] = temp;

            currentLocation = parentLocation;
            parentLocation = (currentLocation - 1) / 2;
            insert_sort(parentLocation, currentLocation);
        }
    }
    
    public int remove() {

        if (currentLocation == 0){
            System.out.println("heap is empty");
            return -1;
        }
        
        // 데이터 삭제 후 배열의 마지막 위치의 값을 첫번째(루트노드) 위치로 이동한다. 
        int remove = array[0];
        array[0] = array[--currentLocation];
        array[currentLocation] = 0;

        // 자식 노드중 보다 큰 값과 정렬을 진행한다. 
        if(array[1] >= array[2]){
            remove_sort(1, 0);
        } else {
            remove_sort(2, 0);
        }
        
        return remove;
    }

    /**
     * 현재값과 자식노드의 값을 비교하여 정렬
     * 
     * @param childLocation
     * @param currentLocation
     */
    private void remove_sort(int childLocation, int currentLocation) {

        if (childLocation < capacity && array[childLocation] > array[currentLocation]) {
            int temp = array[childLocation];
            array[childLocation] = array[currentLocation];
            array[currentLocation] = temp;

            currentLocation = childLocation;
            int leftChild = (currentLocation * 2) + 1;
            int rightChild = (currentLocation * 2) + 2;
            
            // 자식 노드중 보다 큰 값과 정렬을 진행한다. 
            if((leftChild < capacity && rightChild < capacity && array[leftChild] >= array[rightChild]) || (leftChild < capacity && rightChild >= capacity)){
                remove_sort(leftChild, currentLocation);
            } else if ((leftChild < capacity && rightChild < capacity && array[leftChild] < array[rightChild])) {
                remove_sort(rightChild, currentLocation);
            }
        }
    }
    
    
    /**
     * 힙의 데이터를 소팅해서 반환
     * 
     * @return
     */
    public int[] sort() {
        int index = 0;
        int[] array = new int[currentLocation];
        
        while(true) {
            int value = remove();
            
            if(value == -1)
                break;
            
            array[index++] = value;
        } 
        
        return array;
    }

    public void print() {
        for (int i : array) {
            System.out.print(i);
            System.out.print(" ");
        }
        System.out.println("");
    }
}

 

 

참고

http://exynoa.tistory.com/249

http://www.slideshare.net/JoHeeyeon/ss-22500348?qid=079c9306-f027-4ea8-b8e7-1271644bfeee&v=default&b=&from_search=1

 

 

 


반응형
저작자표시 비영리 (새창열림)

'개념 > 자료구조' 카테고리의 다른 글

[Java] 큐(Queue)  (0) 2016.06.10
[JAVA] 스택(Stack)  (3) 2016.06.10
[자료구조] 배열과 링크드 리스트  (0) 2015.06.04
'개념/자료구조' 카테고리의 다른 글
  • [Java] 큐(Queue)
  • [JAVA] 스택(Stack)
  • [자료구조] 배열과 링크드 리스트
hs_seo
hs_seo
Hello World!
    반응형
  • hs_seo
    개발자로 살아남기
    hs_seo
  • 전체
    오늘
    어제
    • 전체 (1140)
      • 개발자 (21)
        • 개발에 유의할 점 (0)
        • 면접 (5)
      • IT 소식 (5)
        • 업계 (1)
      • java (51)
        • 디자인패턴 (3)
        • apache-common (1)
      • 개념 (47)
        • 자료구조 (4)
        • 함수형사고 (8)
        • 디자인패턴 (1)
      • 데이터분석 (1)
      • python (67)
        • 코드조각 (12)
        • 라이브러리 (2)
      • 빅데이터 (418)
        • zookeeper (5)
        • hadoop (78)
        • hdfs (12)
        • hive (127)
        • hbase (16)
        • spark (40)
        • scala (4)
        • trino (3)
        • oozie (41)
        • Hue (9)
        • R (5)
        • sqoop (6)
        • flume (3)
        • elasticsearch (2)
        • airflow (16)
        • kafka (3)
        • kubernetes (10)
        • openstack (3)
        • flink (2)
        • redis (2)
      • 빅데이터 강좌 (2)
      • 알고리즘 (131)
        • 알고리즘 (1)
        • 백준 (61)
        • 정올 (41)
        • 더블릿 (5)
        • 프로그래머스 (1)
      • 프로그래밍 언어 (30)
        • go (4)
        • js (9)
        • .Net (6)
        • Jsp (1)
        • ansible (3)
        • terraform (6)
      • Tools (56)
        • docker (2)
        • macbook (6)
        • maven (3)
        • sublime (1)
      • 프레임워크 (25)
        • [JS] angularjs (2)
        • [JS] node.js (19)
        • [Java] spring (2)
        • Android (2)
      • 데이타베이스 (43)
        • SQLD (5)
        • Oracle (1)
        • MySQL (8)
        • ADsP (2)
      • 리눅스 (25)
        • Bash (61)
      • GCP (5)
      • AWS (34)
        • EC2 (2)
        • EMR (14)
      • 정보보안기사 (4)
        • 네트워크 (1)
      • 개인 (80)
        • 업무실수 (0)
        • 책 (9)
        • 교육 (3)
        • 여행 (17)
        • 영화 (12)
        • 음악 (2)
        • 피규어 (4)
        • 게임 (3)
        • 생각 (7)
        • 기타 (10)
        • 좋은글 (5)
        • 좋은 사이트 (2)
  • 블로그 메뉴

    • 홈
    • 태그
    • 미디어로그
    • 위치로그
    • 방명록
  • 링크

    • 빅데이터-하둡,하이브로 시작하기
    • 빅데이터-스칼라, 스파크로 시작하기
    • Kaggle에서 파이썬으로 데이터 분석 시작하기
    • 쉘스크립트 개발 시작하기
    • 개발자가 데이터 분석 준전문가 되기
    • 데브쿠마
  • 공지사항

  • 인기 글

  • 태그

    파이썬
    emr
    정올
    HDFS
    error
    Hadoop
    AWS
    hbase
    하둡
    다이나믹
    mysql
    Tez
    nodejs
    java
    airflow
    build
    하이브
    Linux
    bash
    SPARK
    oozie
    오류
    백준
    알고리즘
    k8s
    S3
    Python
    yarn
    ubuntu
    HIVE
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.6
hs_seo
[자료구조] 힙과 힙소트
상단으로

티스토리툴바