ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 알고리즘...64
    일지 2021. 10. 7. 14:51

    B 트리 삽입 함수 구현 시작

    먼저 삽입 처리를 수월하게 하기 위해 노드에 삽입 함수를 구현하고 삽입된 키의 개수를 수월하게 관리하기 위해 노드에 현재 키의 개수를 도입한다.

     

    BTree.h

    /// <summary>
    /// B 트리의 노드에서 사용할 키
    /// </summary>
    struct BTreeNodeKey
    {
    	BTreeNodeKey() : left(nullptr), value(0), right(nullptr) {}
    
    	void Clear();
    	void Set(int data);
    
    	BTreeNode* left;
    	int value;
    	BTreeNode* right;
    };
    
    /// <summary>
    /// B 트리에 사용할 노드
    /// </summary>
    struct BTreeNode
    {
    	static const size_t TotalKeyCount{ 4 };
    
    	BTreeNode();
    	~BTreeNode();
    
    	void Clear();
    
    	bool Insert(int data);
    
    	BTreeNode* parent;
    	BTreeNodeKey* keys;
    	size_t size;
    };

     

    BTree.cpp

    /// <summary>
    /// 노드의 키를 초기화한다.
    /// </summary>
    void BTreeNodeKey::Clear()
    {
    	left = nullptr;
    	value = 0;
    	right = nullptr;
    }
    
    /// <summary>
    /// 주어진 값을 키에 저장한다.
    /// </summary>
    /// <param name="data">저장할 값</param>
    void BTreeNodeKey::Set(int data)
    {
    	value = data;
    }
    
    /// <summary>
    /// B 트리 노드 생성자, key를 정해진 개수만큼 생성한다.
    /// </summary>
    BTreeNode::BTreeNode()
    	: parent(nullptr), size(0)
    {
    	keys = new BTreeNodeKey[TotalKeyCount];
    }
    
    /// <summary>
    /// B 트리 소멸자, 생성했던 키를 제거한다.
    /// </summary>
    BTreeNode::~BTreeNode()
    {
    	delete[] keys;
    }
    
    /// <summary>
    /// 노드를 초기화한다.
    /// </summary>
    void BTreeNode::Clear()
    {
    	parent = nullptr;
    	for (int i = 0; i < TotalKeyCount; i++)
    	{
    		keys[i].Clear();
    	}
    }
    
    /// <summary>
    /// 노드에 값을 삽입할 수 있으면 삽입하고 true를 반환하고 아니면 false를 반환한다.
    /// </summary>
    /// <param name="data"></param>
    /// <returns>성공 여부</returns>
    bool BTreeNode::Insert(int data)
    {
    	if (TotalKeyCount <= size)
    	{
    		return false;
    	}
    
    	keys[size++].Set(data);
    
    	return true;
    }

     

    이 과정에서 기존 검색 함수를 조금 더 최적화 할 수 있었다.

     

    BTree::Exists

    /// <summary>
    /// B 트리를 확인하여 주어진 값이 트리에 존재하는지 여부를 반환한다.
    /// </summary>
    /// <param name="data">확인할 값</param>
    /// <returns>존재 여부</returns>
    bool BTree::Exists(int data)
    {
    	BTreeNode* node{ _root };
    	while (node != nullptr)
    	{
    		for (int i = 0; i < node->size; i++)
    		{
    			if (node->keys[i].value == data)
    			{
    				return true;
    			}
    
    			if (data < node->keys[i].value)
    			{
    				node = node->keys[i].left;
    				break;
    			}
    
    			if (node->keys[i].value < data)
    			{
    				if (i == node->size)
    				{
    					node = node->keys[i].right;
    					break;
    				}
    				else if(data < node->keys[i + 1].value)
    				{
    					node = node->keys[i].right;
    					break;
    				}
    			}
    		}
    	}
    	
    	return false;
    }

     

    현재 임시로 루트에 삽입을 하도록 만들었고 이를 일반화한 뒤 오버플로우에 대한 처리를 추가해야 한다.

     

    BTree::Insert

    /// <summary>
    /// 주어진 값을 B 트리에 삽입한다.
    /// </summary>
    /// <param name="data">삽입할 값</param>
    void BTree::Insert(int data)
    {
    	if (_root == nullptr)
    	{
    		_root = _nodeManager.Pop();
    		if (_root->Insert(data))
    		{
    			// 오버플로우 처리
    			// 일반화
    			return;
    		}
    	}
    }

    댓글

Designed by Tistory.