-
B 트리 삽입 알고리즘 문제 파악
삽입이 진행될 때 노드에 공간이 있는 경우 오름차순으로 정렬하여 삽입이 진행되어야 한다.
또, 삽입 후 오버플로우에 대한 처리를 위해 키를 배열로 묶는 게 아닌 포인터로 연결할 필요가 있어 보인다.
#pragma region 노드 /// <summary> /// 노드의 키를 초기화한다. /// </summary> void BTreeNodeKey::Clear() { prev = nullptr; left = nullptr; value = 0; right = nullptr; next = nullptr; } /// <summary> /// 주어진 값을 키에 저장한다. /// </summary> /// <param name="data">저장할 값</param> void BTreeNodeKey::Set(int data) { value = data; } /// <summary> /// B 트리 소멸자, 생성했던 키를 제거한다. /// </summary> BTreeNode::~BTreeNode() { Clear(); } /// <summary> /// 노드를 초기화한다. /// </summary> void BTreeNode::Clear() { parent = nullptr; size = 0; while (keyRoot != nullptr) { BTreeNodeKey* key{ keyRoot }; keyRoot = key->next; key->Clear(); keyManager->Push(key); } } #pragma endregion #pragma region 노드 매니저 /// <summary> /// 노드 매니저 및 키 매니저를 초기화한다. /// </summary> BTreeNodeManager::BTreeNodeManager() { BTreeNode::keyManager = new BTreeNodeKeyManager(); } /// <summary> /// 가지고 있던 노드를 모두 안전하게 제거한다. /// </summary> BTreeNodeManager::~BTreeNodeManager() { while (nodes != nullptr) { BTreeNode* node{ nodes }; nodes = nodes->parent; delete node; } delete BTreeNode::keyManager; } /// <summary> /// 사용 완료한 노드를 저장한다. /// </summary> /// <param name="node">사용 완료한 노드</param> void BTreeNodeManager::Push(BTreeNode* node) { node->parent = nodes; nodes = node; } /// <summary> /// 사용할 노드를 인출한다. /// </summary> /// <returns>사용할 노드</returns> BTreeNode* BTreeNodeManager::Pop() { BTreeNode* node{ nodes }; if (node != nullptr) { nodes = node->parent; node->Clear(); } else { node = new BTreeNode(); } return node; } /// <summary> /// 가지고 있던 키를 모두 안전하게 제거한다. /// </summary> BTreeNodeKeyManager::~BTreeNodeKeyManager() { while (nodes != nullptr) { BTreeNodeKey* node{ nodes }; nodes = nodes->next; delete node; } } /// <summary> /// 사용 완료한 키를 반환한다. /// </summary> /// <param name="node">사용 완료한 키</param> void BTreeNodeKeyManager::Push(BTreeNodeKey* node) { node->next = nodes; nodes = node; } /// <summary> /// 사용할 키를 인출한다. /// </summary> /// <returns>사용할 키</returns> BTreeNodeKey* BTreeNodeKeyManager::Pop() { BTreeNodeKey* node{ nodes }; if (node != nullptr) { nodes = node->next; node->Clear(); } else { node = new BTreeNodeKey(); } return node; } #pragma endregion
삽입 진행은 노드별 키가 2개인 것으로 가정하고 진행한 뒤 키를 늘리는 게 구현하기에 더 편해 보이므로 키의 개수를 변경했다.