heapify의 비 재귀 버전이 있습니다 (아래 예 참조). quicksort의 경우 재귀가 작은 파티션에서만 사용 된 경우 다시 큰 루틴을 2로 분할하고 (다시 2 개의 작은 파티션에서 재귀를 사용하는 등) 최대 스택 공간은 O (로그 n)), 최악의 경우 시간은 여전히 O (n^2)입니다.
C++ 비 재귀 heapify 비 재귀 힙 일종의 예 :
typedef unsigned int uint32_t;
void HeapSort(uint32_t *, size_t);
void Heapify(uint32_t *, size_t);
void SiftDown(uint32_t *, size_t, size_t);
void HeapSort(uint32_t * a, size_t count)
{
size_t end;
Heapify(a, count); // create initial heap
end = count-1;
while(end > 0){
// swap root (largest value) with end
std::swap(a[0], a[end]);
// reduce size of heap and
// increase size of sorted array
end--;
// repair the reduced heap
SiftDown(a, 0, end);
}
}
// create initial heap: for root = (count-2)/2 -> 0
// parent = root, children = root*2+1, root*2+2
// swap so that all a[parent] > a[child]
void Heapify(uint32_t * a, size_t count)
{
size_t root;
if(count < 2)
return;
// create sub-heaps of increasing size,
// with root going from (count-2)/2 to 0
root = (count - 2)/2;
while(1){
SiftDown(a, root, count-1);
if(root == 0)
break;
root--;
}
}
// scan from root to end, swapping as needed to repair or create heap
void SiftDown(uint32_t * a, size_t root, size_t end){
size_t parent;
size_t child;
// while at least two children
for(parent = root; (child = parent * 2 + 2) <= end;){
// choose the larger child
if(a[child-1] > a[child])
child = child-1;
// if child > parent then swap, parent = child
if(a[child] > a[parent]){
std::swap(a[child], a[parent]);
parent = child;
// else done with search for swaps
} else {
break;
}
}
// check for final only child
if((child = parent * 2 + 1) <= end)
if(a[child] > a[parent])
std::swap(a[child], a[parent]);
}
퀵는 O를 구현 바보 않는 공간 (로그 n)를 사용한다. – gnasher729
[왜 힙 정렬에 O (1)의 공간 복잡성이 있습니까?] (http://stackoverflow.com/questions/22233532/why-does-heap-sort-have-a-space-complexity-of -o1) –
Wiki는''O (1)'''을 쓰지 않고''O (1) auxiliary'''! – sascha