2011-04-10 2 views
3

클래스에 대한 선택 정렬 문제를 구현했으며 할당 중 하나는 최소 힙을 사용하여 배열에서 k 번째로 작은 요소를 찾는 것입니다. 나는 절차는 알고최소 힙 정렬을 구현하여 k 번째 최소 요소를 찾는 방법은 무엇입니까?

  • 배열

내가 어떤 문제가 만드는이없는 그룹의 최소 (루트) K 시간

  • 반환 k 번째 작은 요소를 삭제를 heapify 최소 힙. 나는 최소한 k times를 적절히 삭제하고 그룹에서 가장 작은 k 번째 요소를 성공적으로 반환하는 방법을 모를뿐입니다. 여기까지 내가 지금까지 가지고있는 것 :

    bool Example::min_heap_select(long k, long & kth_smallest) const { 
    //duplicate test group (thanks, const!) 
    Example test = Example(*this); 
    
    //variable delcaration and initlization 
    int n = test._total ; 
    int i; 
    
    //Heapifying stage (THIS WORKS CORRECTLY) 
    for (i = n/2; i >= 0; i--) { 
        //allows for heap construction 
        test.percolate_down_protected(i, n); 
    }//for 
    
    
    //Delete min phase (THIS DOESN'T WORK) 
    for(i = n-1; i >= (n-k+1); i--) { 
    
    
        //deletes the min by swapping elements 
        int tmp = test._group[0]; 
        test._group[0] = test._group[i]; 
        test._group[i] = tmp;  
    
        //resumes perc down 
        test.percolate_down_protected(0, i);   
    
    
    }//for 
    
        //IDK WHAT TO RETURN 
        kth_smallest = test._group[0]; 
    
    
    
    void Example::percolate_down_protected(long i, long n) { 
    
    //variable declaration and initlization:  
    int currPos, child, r_child, tmp; 
    currPos = i; 
    tmp = _group[i]; 
    child = left_child(i); 
    
    //set a sentinel and begin loop (no recursion allowed) 
    while (child < n) { 
    
        //calculates the right child's position 
        r_child = child + 1; 
    
        //we'll set the child to index of greater than right and left children 
        if ((r_child > n) && (_group[r_child] >= _group[child])) { 
         child = r_child; 
        } 
        //find the correct spot 
        if (tmp <= _group [child]) { 
         break; 
        } 
    
        //make sure the smaller child is beneath the parent 
        _group[currPos] = _group[child]; 
    
        //shift the tree down 
        currPos = child; 
        child = left_child(currPos); 
    } 
    
    //put tmp where it belongs 
    _group[currPos] = tmp; 
    } 
    

    앞에서 언급했듯이, 최소 힙 부품은 올바르게 작동합니다. 내가 무엇을 해야할지 이해한다. 루트 k 번을 지우는 것이 쉽지만 배열의 어떤 인덱스를 반환 할 것인가 ... 0? 이것은 거의 작동합니다. k = n 또는 k = 1로 가치가 없습니다. k 번째 가장 작은 요소가 Any help에 있으면 많은 도움이됩니다!

  • 답변

    6

    사용자에게 의미있는 유일한 배열 인덱스는 0이며 최소 요소입니다. 따라서 k 개의 요소를 제거한 후 k '번째로 작은 요소는 0이됩니다.

    아마 힙을 파기하고 힙 자체에 대해 사용자에게 묻는 대신 값을 반환해야하지만 할당의 세부 사항을 알 수는 없습니다.

    C++ 표준 라이브러리에는 make_heap, pop_heapnth_element과 같이 도움이되는 알고리즘이 있습니다.

    +0

    오해를 막기 위해 make_heap과 pop_heap은 min_heap을 처리합니다. nth_element는 * 없습니다 * (일반적으로 QuickSelect의 중간 변형 변형의 중간 값을 사용합니다). –

    +0

    @ 제리 : 예. 'nth_element'는 주어진 배열을 부분적으로 정렬하며, 힙 기반 메소드보다 빠를 가능성이 높습니다. – Potatoswatter

    +0

    답변 해 주셔서 감사합니다. 이 과제에 C++ SL을 사용할 수 없습니다. 그것을 통해 일하고 내 실수가 뭔지 깨달았다 - 간단한 카운터 조정! – thomascirca

    관련 문제