여러 가지 이유로 B + 트리를 작성 중이며 노드 구현에 대해 질문하고 있습니다. 내 현재의 구현 * 사용하고 볼 수있는 것처럼 내가 * * 또는 * 사용할지 여부를 궁금 어디 장소에서 *B + 트리 구현, * * vs *
struct BPlusNode
{
public:
//holds the list of keys
keyType **keys;
//stores the number of slots used
size_t size;
//holds the array of pointers to lower nodes NULL if this is a leaf node
BPlusNode **children;
//holds the pointer to the next load to the 'left'
BPlusNode *next;
//Data page pointers NULL if this is a branch node
Bucket **pages;
};
: 내 노드는 현재처럼 보인다.
* *는 두 개의 역 참조 연산을 필요로하므로 *를 사용하는 것보다 느리다는 것을 잘 알고 있지만이 클래스는 많은 재귀를 사용하며 하위 호출에 대한 포인터를 전달하는 것이 훨씬 편리합니다. 재귀 함수. 이것을하기 위해서 포인터 연산을하고 결과 포인터를 전달해야합니다.
와 **someFunction(BPlusNode* currNode)
{
......
someFunction(currNode->children[ChildIndex]);
}
함께
*
someFunction(BPlusNode* currNode)
{
......
someFunction((currNode->children) + ChildIndex);
}
I에서, * 버전 원하는 포인터를 생성하기 위해 메모리의 추가 판독이 있다는 것을 알 수 있지만 * * 버전은 나를 생각하기에 더 쉽습니다 ("The Art of Computer Programming"과 위키 피 디아에서 그려진 다이어그램을 보는 방법과 더 비슷합니다).
누구에게 어떤 생각이 있습니까? 세 번째 옵션에 대한 제안? 왜 다른 사람보다 우월한 증거? 기타?
편집 :
아래 답변을 게시 할 수 있지만 * * 스키마를 사용하면 각 하위 노드 또는 버킷의 전체 내용을 복사 할 필요가 없다는 것을 깨달았습니다. 배열 (즉, 배열의 크기를 변경) 배열을 다시 할당 할 때 * 스키마에 20 개의 하위 노드가있는 경우 20 * sizeof (BPlusNode) 바이트를 복사해야하며 * * scheme의 경우 20 * sizeof (BPlusNode *) 바이트가 필요합니다.
반면에 나는 모든 인서트와 페이지 분할을 수행했기 때문에 이러한 성능 향상은 불필요하며 검색에서 * * *의 이점이 더 중요 할 수도 있습니다.
태그가 C++이므로 포인터 연산 대신 참조로 포인터를 전달할 수없는 이유가 있습니까? – greyfade
someFunction (BPlusNode * & currNode) ....와 같이하고 someFunction (currNode-> children [ChildIndex])에 의해 호출하면 * *보다 더 나쁠 수 있습니다. []는 기본적으로 * (currNode-> children + ChildIndex)와 같으므로 * * 스키마와 동일하게 포인터 산술, 참조 해제가 있습니다. * * 스킴과는 달리 객체에 대한이 포인터는 검색되어 통과되어야합니다. 그래서 효율면에서 적어도 * * 계획과 같습니다. 아마 더 나빠질 수 있습니다. –
@James : greyfade가'someFunction (BPlusNode & currNode)'의 서명을 제안하고 있다고 확신합니다. 이것은 'someFunction (BPlusNode * currNode)'와 기능적으로 (그리고 성능 측면에서) 보이지만 깨끗하게 보이고 실수로 pointee 오브젝트 대신 포인터를 변경하여 발생할 수있는 오류를 피할 수 있습니다. –