2013-09-28 4 views
0

많은 노드 (수백만 개 이상)가 있고 메모리에로드해야하는 트리가 있습니다. 따라서 노드와 노드의 관계를 메모리에 저장하는 가장 효율적인 방법이 필요합니다. 가장 적합한 데이터 구조는 무엇입니까? 내가 삭제 및 삽입, 브라우징 등이 나무에 같은 작업을 수행 할 필요가,최적의 트리 데이터 구조

//more obvious but the less efficient 
class TreeNode 
{ 
Node parent; 
TreeNode[] children; 

//additional fields 
byte X; 
byte Y; 
byte marker; 
string comment; 
} 

//more efficient 
class TreeNode 
{ 
TreeNode next; //reference to the next child of parent node, 
       //if isLast=true - reference to parent node 

TreeNode firstChild; //reference to the first child of this node 

bool isLast; //true, if this node is the last parents child 

//additional fields 
byte X; 
byte Y; 
byte marker; 
string comment; 
} 

주, 나는이 충분히 빨리해야합니다 지금까지, 나는 두 가지 옵션이 있습니다.

편집 :이 경우에 가장 적합한 RAM은 전체 트리를 저장하는 데 사용됩니다. 두 번째 기준은 빠른 삭제, 찾아보기 및 삽입 작업입니다. 위에서 쓴 데이터 구조에서는 시간이 많이 걸릴 수 없습니다. 나는이 기준을 더 엄격하게 공식화 할 수 없다.

+0

이 용도로 F #을 사용하는 것이 좋습니다. –

+0

제목을 편집했습니다. "[제목에"태그 "가 포함되어 있어야합니까?] (http://meta.stackexchange.com/questions/19190/)"합의가 "아니오, 그렇지 않아야합니다"로 표시되어야합니다. –

+0

표준 트리 알고리즘이 작동하지만, 노드를 단일 List <>로 구조화하고 참조가 아닌 인덱스를 사용하여 참조하는 경우 GC에서 훨씬 더 쉽습니다. –

답변

0

당신은 돌연변이 인 메모리 내 데이터 세트를 가지고있는 것처럼 들린다. 그렇다면 어떤 작업이 공통인지 파악하는 것이 매우 중요합니다. 예를 들어 "찾아보기"라고 말하면, 검색입니까? 아니면 현재보고있는 노드의 부모 또는 자식에 대한 간단한 탐색입니까?

검색의 경우 일반적으로 첫 번째 작업 (예 : 값이있는 노드를 찾은 다음 무언가를 수행) 인 경우 Red/Black Tree을 사용하는 것이 좋습니다. 이 구조는 검색, 삽입 및 삭제를 위해 로그를 n 시간 사용합니다. 삽입 및 삭제 중에 부과 된 규칙은 트리를 검색에 맞게 최적화 된 상태로 유지합니다.

검색 속도가 중요하지 않은 경우 간단한 트리 구조를 사용하여 삽입 및 제거 속도를 높일 수 있습니다.

레드 트리/블랙 트리는 다른 모든 트리 구조와 마찬가지로 n 개의 공간을 차지합니다. 이것은 구조 자체에 대해서도 마찬가지입니다. 그러나 창조적 인 조치를 취할 수 있기 때문에 마음을 가져라.

예를 들어 각 노드에 3 바이트와 문자열을 저장합니다. 이 데이터의 하위 집합 만 메모리에 저장하고 필요에 따라 영구 저장소 (예 : 데이터베이스)에서 나머지 데이터를 조회 할 수 있습니까? 표준 트리 작업에는 불필요한 데이터가 필요하지만 어쩌면 수행 할 수 있습니다. 또는 문자열 데이터를 메모리에 압축 할 수 있습니까?

+1

힌트를 보내 주셔서 감사합니다. 내 경우에 가장 일반적으로 사용되는 작업은 여러 트리를 병합해야 할 때 종종 탐색 (트리 위아래로) 및 삽입입니다. 또한 해당 3 바이트에 포함 된 추가 정보로 검색하십시오. 예, 나는이 추가 3 바이트와 문자열의 최적화에 대해 생각하고 있었지만, 사실 공간의 대부분은 클래스 참조 (string ref, next 및 firstchild refs)에 의해 소비되었습니다. 추가 최적화를 위해 생각하고있는 것은로드 후 트리의 일부를 캐싱 (예 : 깊이가 40보다 큰 노드 또는 다른 조건)하고 첫 번째 요청 후에 다시로드하는 것입니다. – DizzyBlack

+0

검색 및 로딩 속도가 느려지지만 좋은 타협점을 찾을 수 있다고 생각합니다. – DizzyBlack

0

C++ 유형의 구조체로 직접 작업 한 이후로 꽤 오랜 시간이 걸렸지 만, 내가했을 때 btree 구조체로 작업하고있었습니다. 전제는 비슷하지만 단일 노드에서 레벨 당 8 (또는 그 이상의) 키를 말할 수 있습니다. 하지만 수백만 가지 항목을 다루는 경우 살펴볼 항목이있을 수 있습니까?

최상위 노드에는 8 개의 키가 있고, 90k 항목의 트리를 정신적으로 이해하기 쉽도록 최상위 노드는 10k, 20k, 30k ... 80k입니다. 그래서 당신이 찾고있는 숫자가 10k보다 적 으면 그것은 다리입니다 ... 20k 미만이 다리처럼됩니다. 그래서 단일 노드 레벨에서 사용 가능한 몇 가지 요소를 테스트하면 기본적으로 다른 80k.

예를 들어 26,895를 찾고 계십시오. 최상위 노드에서 시작하여 원하는 30k를 얻습니다 (30k 미만이지만 20k 이상). 이제 다음 노드가로드됩니다. 그러나이 노드는 20,001에서 29,999까지 확장됩니다. 웃음 소리는 21250, 22500, 23750, 2500, 26250, 27500, 28750, 29999입니다 (각각 1250의 나누기). 이제는 27500을 기록했습니다. 그보다 작 으면 1 레벨 더 깊어집니다. 이 레벨은 현재 26250에서 27499까지의 차이를 가지고 있으며 두 번째 레벨에 불과합니다.

분명히 책이나 강력한 참조가 필요하지만 분명히 강력하고 빠를 수 있습니다.

+0

힌트를 보내 주셔서 감사합니다! 내 문제가 더욱 중요해지면서 btree를 조사 할 것입니다. – DizzyBlack