C에서 영구 데이터 구조의 구현은 기본적으로 함수 언어에서와 같은 방식으로 작동합니다. Chris Okasaki의 Purely Functional Data Structures은 훌륭한 참고 자료입니다.
일반적으로 은 본격적인 사전을 제공하지 않지만 고정 길이 정수는 개체에 매핑하면 충분합니다. 실제 키의 해시를 사용하십시오. 기본 맵의 키로 사용하고 리프가 동일한 해시 값의 (키, 값) 쌍 목록을 가리 키도록합니다.
까다로운 부분은 일반적으로 데이터 구조의 일부가 도달 할 수없는 시점을 알지 못하기 때문에 메모리 관리입니다. 다행히 대부분의 영구 데이터 구조는 나무를 기반으로하기 때문에 일반적으로 참조 계산이 잘 작동합니다. 데이터 구조에서 참조하는 객체를 관리하려면 리프 노드의 참조 수가 0이 될 때 호출되는 콜백에 대한 후크를 제공 할 수 있습니다.
예를 들어, 비트 맵핑 된 Patricia Trees의 myC 구현은 다음을 제공합니다. API :
// Querying
void *bpt_get(bpt_t bpt, bpt_key_t key);
bool bpt_has_key(bpt_t bpt, bpt_key_t key);
// Adding and Removing Entries
bpt_t bpt_assoc(bpt_t bpt, bpt_key_t key, void *item);
bpt_t bpt_dissoc(bpt_t bpt, bpt_key_t key);
// Managing Memory
void bpt_retain(bpt_t bpt);
void bpt_release(bpt_t bpt);
void bpt_dealloc(bpt_t bpt);
void bpt_set_dealloc_hook(bpt_t bpt,
bpt_key_t key,
void (*hook)(bpt_key_t key,
void* value));
// Iteration
void bpt_for_mappings(bpt_t bpt,
void (*thunk)(bpt_key_t, void*, void*),
void *user_data);
// Making a Map Persistent (you can elide this if you don't
// want to support transients)
void bpt_seal(bpt_t bpt);
implementation도 몇 가지 아이디어를 줄 수 있습니다.
답변 해 주셔서 감사합니다. 메모리 관리는 제 문제가 아닙니다. 이미 참조 계산을 사용하여 트리 구현을 작성했습니다. 내가 찾고있는 기능 사전 구현 - 일정한 조회 시간을 가진 데이터 구조입니다. 나무는 대개 로그 조회 복잡성 만 제공합니다. 오카사키 (Okasaki) 지에서 사전에 대한 참조를 찾을 수 없습니다. – mirkokiefer
@mirkok 조회 시간 만 중요한 경우, 물론 해시 테이블을 사용하여 모든 업데이트에서 복사 할 수 있습니다. 항상 상충 관계에 있습니다. 즉, 비트 맵핑을 사용하여 시도를 조정할 수 있습니다 (구현시 Clojure의 PersistentHashMap 않습니다. 다른 개발자도 마찬가지입니다). 비트 맵핑에서는 액세스가 여전히 로그되지만 기본은 더 큽니다. 이론상 (실제로는 항상 그런 것은 아니지만) 복사 오버 헤드는 증가하지만 리프에 도달하는 데 필요한 홉 수는 줄어 듭니다. 32 비트 비트 맵을 사용하면 2^32 키가 최대 7 레벨에 해당합니다. –