여기에있는 대부분의 답변이 잘못되었습니다 . 정답은 그것이 달려 있다는 것 입니다. 예를 들어, 트리를 통과하는 두 개의 C 함수가 있습니다. 먼저 재귀 적 인 것 :
static
void mm_scan_black(mm_rc *m, ptr p) {
SET_COL(p, COL_BLACK);
P_FOR_EACH_CHILD(p, {
INC_RC(p_child);
if (GET_COL(p_child) != COL_BLACK) {
mm_scan_black(m, p_child);
}
});
}
그리고 반복을 사용하여 구현 된 동일한 기능은 다음과 같습니다.
static
void mm_scan_black(mm_rc *m, ptr p) {
stack *st = m->black_stack;
SET_COL(p, COL_BLACK);
st_push(st, p);
while (st->used != 0) {
p = st_pop(st);
P_FOR_EACH_CHILD(p, {
INC_RC(p_child);
if (GET_COL(p_child) != COL_BLACK) {
SET_COL(p_child, COL_BLACK);
st_push(st, p_child);
}
});
}
}
코드의 세부 사항을 이해하는 것은 중요하지 않습니다. 그것은 바로 p
노드이며 P_FOR_EACH_CHILD
걷는 것입니다. 반복 버전에서는 st
노드를 푸시 한 다음 팝 및 조작 할 명시 적 스택이 필요합니다 .
재귀 함수는 반복 함수보다 훨씬 빠르게 실행됩니다. 그 이유는 후자에서 각 항목에 대해 a CALL
기능 st_push
이 필요하고 다른 항목 이 필요하기 때문 st_pop
입니다.
전자에서는 CALL
각 노드에 대한 재귀 만 있습니다 .
또한 콜 스택에서 변수에 액세스하는 것이 매우 빠릅니다. 항상 가장 안쪽에있는 메모리에서 읽을 수 있음을 의미합니다. 반면에 명시 적 스택 malloc
은 힙에서 : ed 메모리 로 백업 해야하므로 액세스 속도가 훨씬 느립니다.
인라인 st_push
및과 같은 신중한 최적화 st_pop
를 통해 재귀 적 접근 방식으로 대략적인 패리티에 도달 할 수 있습니다. 그러나 적어도 내 컴퓨터에서는 힙 메모리 액세스 비용이 재귀 호출 비용보다 큽니다.
그러나이 논의는 재귀적인 트리 워킹이 잘못 되었기 때문에 대부분 헛소리 입니다. 트리가 충분히 크면 콜 스택 공간이 부족하므로 반복 알고리즘을 사용해야합니다.