B+ Tree

本文详细介绍了B+树的特性,包括叶子节点存储value,普通节点存储key,以及节点key数量的限制。接着,通过插入一系列数值来展示B+树的插入过程,记录了每次插入后的树结构变化。在删除操作部分,展示了如何在B+树中查找、删除指定key,并根据删除后节点的keysize调整树结构,包括合并节点和分裂节点等步骤。整个过程揭示了B+树在数据存储和检索上的高效性和稳定性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

B+ tree 的特点

(1)在叶子节点存储value,其他的存储key
(2)普通的node(非叶子和根)child的个数>=key的个数
m==5 则key个数=[m/2, m-1],也就是[2,4],child的个数>=key的个数,[2,5]
请添加图片描述
请添加图片描述

insert 操作

(1)找到合适的叶子节点,执行(2)
(2)在叶子节点进行插入,执行(3)
(3)判断该叶子节点key的数量是否超过最大值,不超过则结束,否则(4)
(4)均分该叶子节点,并上移中间的key的值到父节点,现在处理的节点变成父节点,跳到(3),一直循环,直到处理节点的父节点keysize大小合适

插入{5,8,10,15,16,17,18, 19,20,21,22,6,9,7};

[+] log construction, can use it  C:\Desktop\t\PaintTree/_log/log.html
[0]06:15:59[info][5864] [Start::doSomething]    test  1   (Start.cpp:29)
[1]06:15:59[info][5864] [Start::doSomething]    insert start   (Start.cpp:30)
[2]06:15:59[test][5864] [BPTree<int,char>::insert]      insert   _key:  5  _value:  E   (BPTree.h:65)
[3]06:15:59[debg][5864] [BPTree<int,char>::insert]      find leaf     (BPTree.h:67)
[4]06:15:59[debg][5864] [BPTree<int,char>::insert]      insert node,  <(5:E),>   (BPTree.h:78)
[5]06:15:59[debg][5864] [BPTree<int,char>::insert]      all tree :

<(5:E),P:>
   (BPTree.h:81)
[6]06:15:59[test][5864] [BPTree<int,char>::insert]      insert   _key:  8  _value:  H   (BPTree.h:65)
[7]06:15:59[debg][5864] [BPTree<int,char>::insert]      find leaf  <(5:E),>   (BPTree.h:67)
[8]06:15:59[test][5864] [BPTree<int,char>::insert]      <(5:E),>  loc:  1  _key:  8  _value:  H  is_exist_key:  0   (BPTree.h:75)
[9]06:15:59[debg][5864] [BPTree<int,char>::insert]      insert node,  <(5:E),(8:H),>   (BPTree.h:78)
[10]06:15:59[debg][5864]        [BPTree<int,char>::insert]      all tree :

<(5:E),(8:H),P:>
   (BPTree.h:81)
[11]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  10  _value:  J   (BPTree.h:65)
[12]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(5:E),(8:H),>   (BPTree.h:67)
[13]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(5:E),(8:H),>  loc:  2  _key:  10  _value:  J  is_exist_key:  0   (BPTree.h:75)
[14]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(5:E),(8:H),(10:J),>   (BPTree.h:78)
[15]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<(5:E),(8:H),(10:J),P:>
   (BPTree.h:81)
[16]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  15  _value:  O   (BPTree.h:65)
[17]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(5:E),(8:H),(10:J),>   (BPTree.h:67)
[18]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(5:E),(8:H),(10:J),>  loc:  3  _key:  15  _value:  O  is_exist_key:  0   (BPTree.h:75)
[19]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(5:E),(8:H),(10:J),(15:O),>   (BPTree.h:78)
[20]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<(5:E),(8:H),(10:J),(15:O),P:>
   (BPTree.h:81)
[21]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  16  _value:  P   (BPTree.h:65)
[22]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(5:E),(8:H),(10:J),(15:O),>   (BPTree.h:67)
[23]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(5:E),(8:H),(10:J),(15:O),>  loc:  4  _key:  16  _value:  P  is_exist_key:  0   (BPTree.h:75)
[24]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(5:E),(8:H),(10:J),(15:O),(16:P),>   (BPTree.h:78)
[25]06:16:00[debg][5864]        [BPTree<int,char>::adjustmentNodeAfterInsert]   getNodeInfo(left_node):  <(5:E),(8:H),>  move_up_key:  8  getNodeInfo(right_node):  <(10:J),(15:O),(16:P),>   (BPTree.h:131)
[26]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,P:>
<(5:E),(8:H),P:<8,>> <(10:J),(15:O),(16:P),P:<8,>>
   (BPTree.h:81)
[27]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  17  _value:  Q   (BPTree.h:65)
[28]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(10:J),(15:O),(16:P),>   (BPTree.h:67)
[29]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(10:J),(15:O),(16:P),>  loc:  3  _key:  17  _value:  Q  is_exist_key:  0   (BPTree.h:75)
[30]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(10:J),(15:O),(16:P),(17:Q),>   (BPTree.h:78)
[31]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,P:>
<(5:E),(8:H),P:<8,>> <(10:J),(15:O),(16:P),(17:Q),P:<8,>>
   (BPTree.h:81)
[32]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  18  _value:  R   (BPTree.h:65)
[33]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(10:J),(15:O),(16:P),(17:Q),>   (BPTree.h:67)
[34]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(10:J),(15:O),(16:P),(17:Q),>  loc:  4  _key:  18  _value:  R  is_exist_key:  0   (BPTree.h:75)
[35]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(10:J),(15:O),(16:P),(17:Q),(18:R),>   (BPTree.h:78)
[36]06:16:00[debg][5864]        [BPTree<int,char>::adjustmentNodeAfterInsert]   getNodeInfo(left_node):  <(10:J),(15:O),>  move_up_key:  15  getNodeInfo(right_node):  <(16:P),(17:Q),(18:R),>   (BPTree.h:131)
[37]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,15,P:>
<(5:E),(8:H),P:<8,15,>> <(10:J),(15:O),P:<8,15,>> <(16:P),(17:Q),(18:R),P:<8,15,>>
   (BPTree.h:81)
[38]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  19  _value:  S   (BPTree.h:65)
[39]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(16:P),(17:Q),(18:R),>   (BPTree.h:67)
[40]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(16:P),(17:Q),(18:R),>  loc:  3  _key:  19  _value:  S  is_exist_key:  0   (BPTree.h:75)
[41]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(16:P),(17:Q),(18:R),(19:S),>   (BPTree.h:78)
[42]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,15,P:>
<(5:E),(8:H),P:<8,15,>> <(10:J),(15:O),P:<8,15,>> <(16:P),(17:Q),(18:R),(19:S),P:<8,15,>>
   (BPTree.h:81)
[43]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  20  _value:  T   (BPTree.h:65)
[44]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(16:P),(17:Q),(18:R),(19:S),>   (BPTree.h:67)
[45]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(16:P),(17:Q),(18:R),(19:S),>  loc:  4  _key:  20  _value:  T  is_exist_key:  0   (BPTree.h:75)
[46]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(16:P),(17:Q),(18:R),(19:S),(20:T),>   (BPTree.h:78)
[47]06:16:00[debg][5864]        [BPTree<int,char>::adjustmentNodeAfterInsert]   getNodeInfo(left_node):  <(16:P),(17:Q),>  move_up_key:  17  getNodeInfo(right_node):  <(18:R),(19:S),(20:T),>   (BPTree.h:131)
[48]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,15,17,P:>
<(5:E),(8:H),P:<8,15,17,>> <(10:J),(15:O),P:<8,15,17,>> <(16:P),(17:Q),P:<8,15,17,>> <(18:R),(19:S),(20:T),P:<8,15,17,>>
   (BPTree.h:81)
[49]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  21  _value:  U   (BPTree.h:65)
[50]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(18:R),(19:S),(20:T),>   (BPTree.h:67)
[51]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(18:R),(19:S),(20:T),>  loc:  3  _key:  21  _value:  U  is_exist_key:  0   (BPTree.h:75)
[52]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(18:R),(19:S),(20:T),(21:U),>   (BPTree.h:78)
[53]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,15,17,P:>
<(5:E),(8:H),P:<8,15,17,>> <(10:J),(15:O),P:<8,15,17,>> <(16:P),(17:Q),P:<8,15,17,>> <(18:R),(19:S),(20:T),(21:U),P:<8,15,17,>>
   (BPTree.h:81)
[54]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  22  _value:  V   (BPTree.h:65)
[55]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(18:R),(19:S),(20:T),(21:U),>   (BPTree.h:67)
[56]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(18:R),(19:S),(20:T),(21:U),>  loc:  4  _key:  22  _value:  V  is_exist_key:  0   (BPTree.h:75)
[57]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(18:R),(19:S),(20:T),(21:U),(22:V),>   (BPTree.h:78)
[58]06:16:00[debg][5864]        [BPTree<int,char>::adjustmentNodeAfterInsert]   getNodeInfo(left_node):  <(18:R),(19:S),>  move_up_key:  19  getNodeInfo(right_node):  <(20:T),(21:U),(22:V),>   (BPTree.h:131)
[59]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,15,17,19,P:>
<(5:E),(8:H),P:<8,15,17,19,>> <(10:J),(15:O),P:<8,15,17,19,>> <(16:P),(17:Q),P:<8,15,17,19,>> <(18:R),(19:S),P:<8,15,17,19,>> <(20:T),(21:U),(22:V),P:<8,15,17,19,>>
   (BPTree.h:81)
[60]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  6  _value:  F   (BPTree.h:65)
[61]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(5:E),(8:H),>   (BPTree.h:67)
[62]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(5:E),(8:H),>  loc:  1  _key:  6  _value:  F  is_exist_key:  0   (BPTree.h:75)
[63]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(5:E),(6:F),(8:H),>   (BPTree.h:78)
[64]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,15,17,19,P:>
<(5:E),(6:F),(8:H),P:<8,15,17,19,>> <(10:J),(15:O),P:<8,15,17,19,>> <(16:P),(17:Q),P:<8,15,17,19,>> <(18:R),(19:S),P:<8,15,17,19,>> <(20:T),(21:U),(22:V),P:<8,15,17,19,>>
   (BPTree.h:81)
[65]06:16:00[test][5864]        [BPTree<int,char>::insert]      insert   _key:  9  _value:  I   (BPTree.h:65)
[66]06:16:00[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(10:J),(15:O),>   (BPTree.h:67)
[67]06:16:00[test][5864]        [BPTree<int,char>::insert]      <(10:J),(15:O),>  loc:  0  _key:  9  _value:  I  is_exist_key:  0   (BPTree.h:75)
[68]06:16:00[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(9:I),(10:J),(15:O),>   (BPTree.h:78)
[69]06:16:00[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,15,17,19,P:>
<(5:E),(6:F),(8:H),P:<8,15,17,19,>> <(9:I),(10:J),(15:O),P:<8,15,17,19,>> <(16:P),(17:Q),P:<8,15,17,19,>> <(18:R),(19:S),P:<8,15,17,19,>> <(20:T),(21:U),(22:V),P:<8,15,17,19,>>
   (BPTree.h:81)
[70]06:16:01[test][5864]        [BPTree<int,char>::insert]      insert   _key:  7  _value:  G   (BPTree.h:65)
[71]06:16:01[debg][5864]        [BPTree<int,char>::insert]      find leaf  <(5:E),(6:F),(8:H),>   (BPTree.h:67)
[72]06:16:01[test][5864]        [BPTree<int,char>::insert]      <(5:E),(6:F),(8:H),>  loc:  2  _key:  7  _value:  G  is_exist_key:  0   (BPTree.h:75)
[73]06:16:01[debg][5864]        [BPTree<int,char>::insert]      insert node,  <(5:E),(6:F),(7:G),(8:H),>   (BPTree.h:78)
[74]06:16:01[debg][5864]        [BPTree<int,char>::insert]      all tree :

<8,15,17,19,P:>
<(5:E),(6:F),(7:G),(8:H),P:<8,15,17,19,>> <(9:I),(10:J),(15:O),P:<8,15,17,19,>> <(16:P),(17:Q),P:<8,15,17,19,>> <(18:R),(19:S),P:<8,15,17,19,>> <(20:T),(21:U),(22:V),P:<8,15,17,19,>>
   (BPTree.h:81)


插入5:
请添加图片描述
插入8
请添加图片描述
插入10
请添加图片描述
插入15
请添加图片描述
插入16
请添加图片描述
插入17,请添加图片描述

插入18,
请添加图片描述

插入 19,
请添加图片描述

插入20,
请添加图片描述

插入21,
请添加图片描述

插入22,
请添加图片描述

插入6,
请添加图片描述

插入9,
请添加图片描述

插入7
请添加图片描述

	void insert(const_key_type_reference _key,value_type  _value) {
		//1.find proper leaf
		LOGXT("insert ", VAR_DATA(_key), VAR_DATA(_value));
		auto [node_leaf, loc,is_exist_key] = findProperLeaf(_key);
		LOGXD("find leaf", getNodeInfo(node_leaf));
		if (getRoot() == nullptr) {
			getRoot() = new node_type(true);
			node_leaf = getRoot();
			getRoot()->getKeys().emplace_back(_key);
			getRoot()->getValues().emplace_back(_value);
		}
		else {
			LOGXT(getNodeInfo(node_leaf), VAR_DATA(loc), VAR_DATA(_key), VAR_DATA(_value), VAR_DATA(is_exist_key));
			leafNodeInsert(node_leaf, loc, _key, _value, is_exist_key);
		}
		LOGXD("insert node,",getNodeInfo(node_leaf));
		adjustmentNodeAfterInsert(node_leaf);

		LOGXD("all tree :", displayTree());
	}
	std::tuple<node_type_ptr, key_type, node_type_ptr> splitNode(node_type_ptr _node, size_type _loc) {
		/// <summary>
		/// loc : [1,2,3,4] ,loc=1-->2,
		/// </summary>
		/// <param name="_node"></param>
		/// <param name="_loc"></param>
		/// <returns></returns>
		node_type_ptr left_node = nullptr;
		node_type_ptr right_node = nullptr;
		key_type move_up_key;
		do {
			if (_node == nullptr)break;
			if (_loc == 0)break;
			auto& keys = _node->getKeys();
			if (keys.size() <= _loc)break;;
			bool is_leaf = _node->isLeaf();
			right_node = new node_type(is_leaf);
			right_node->getParent() = _node->getParent();
			//======================================================
			move_up_key = keys[_loc-1];
			(right_node->getKeys()).insert(right_node->getKeys().begin(), keys.begin() + _loc, keys.end());
			keys.erase(keys.begin() + _loc, keys.end());
			if (is_leaf) {
				right_node->getNext() = _node->getNext();
				_node->getNext() = right_node;
				auto& values = _node->getValues();
				(right_node->getValues()).insert(right_node->getValues().begin(), values.begin() + _loc, values.end());
				values.erase(values.begin() + _loc, values.end());
			}
			else {
				auto& values = _node->getChilds();
				right_node->getChilds().insert(right_node->getChilds().begin(), values.begin() + _loc, values.end());
				values.erase(values.begin() + _loc, values.end());
			}

			updataChildParent(left_node);
			updataChildParent(right_node);
		} while (false);
		return std::tuple(_node, move_up_key, right_node);
	}
	void adjustmentNodeAfterInsert(node_type_ptr _node) {
		do {
			if(_node==nullptr)break;
			auto& keys = _node->getKeys();
			if (keys.size() <= getNodeMaxSize())break;

			size_type loc = (getNodeMaxSize()+1) / 2;
			auto [left_node, move_up_key, right_node] = splitNode(_node,loc);
			LOGXD(VAR_DATA(getNodeInfo(left_node)), VAR_DATA(move_up_key), VAR_DATA( getNodeInfo(right_node)));


			if (_node == getRoot()) {
				node_type_ptr new_root = new node_type(false);
				auto& new_keys = new_root->getKeys();
				auto& new_childs = new_root->getChilds();
				new_childs.emplace_back(left_node);
				new_keys.emplace_back(move_up_key);
				new_childs.emplace_back(right_node);
				new_root->getParent() = nullptr;
				getRoot() = new_root;
				updataChildParent(new_root);
			}
			else {
				node_type_ptr parent = _node->getParent();
				auto& parent_keys = parent->getKeys();
				auto& parent_childs = parent->getChilds();
				auto [is_eixst,loc]= findProperKeyindex(parent, move_up_key);
				parent_keys.insert(parent_keys.begin() + loc, move_up_key);
				parent_childs.insert(parent_childs.begin() + loc+1, right_node);
			}

			adjustmentNodeAfterInsert(_node->getParent());

		} while (false);
	}
		//tool
	std::tuple<bool, size_type> findProperKeyindex(node_type_ptr _node, const_key_type_reference _key) {
		/// <summary>
		///  bool if exist key will true
		///	 size_type is proper index
		/// </summary>
		/// <param name="_key"></param>
		/// <returns></returns>
		node_type_ptr node = _node;
		auto keys = node->getKeys();
		const size_type len = keys.size();
		bool is_exist = false;
		size_type loc = -1;
		if (_node == nullptr)return std::tuple(is_exist, loc);
		for (size_type i = 0; i < len; i++) {
			loc = i;
			if (keys[i] > _key)break;
			if (keys[i] == _key) { is_exist = true; break; }
			if (len == i + 1)loc += 1;
		}
		
		return std::tuple(is_exist, loc);
	}
	std::tuple<node_type_ptr, size_type,bool> findProperLeaf(const_key_type_reference _key) {
		node_type_ptr node = getRoot();
		size_type loc_ = -1;
		bool is_exist_key_ = false;
		while (true) {
			if (node == nullptr) {
				loc_ = 0;
				break;
			}
			auto [is_exist_key, loc] = findProperKeyindex(node, _key);

			if (node->isLeaf()) {
				loc_ = loc;
				is_exist_key_ = is_exist_key;
				break;
			}
			node = node->getChilds()[loc];
		}
		return std::tuple(node, loc_,is_exist_key_);
	}
remove

(1)找到叶子节点中是否存在key,如果不存在,结束,否则(2)
(2)在找到的叶子节点进行删除key以及value操作,到(3)
(3)判断当前叶子节点的key size ,如果>=key_min_size ,结束,否则(4)
(4)当前叶子节点是否根节点,如果是,判断key size ==0 ,那就delete root,root=ullptr,key size !=0 则结束, 叶子节点不是根节点的话,则寻找兄弟节点,到(5)
(5)兄弟节点key size > key_min_size ,则移动兄弟节点的key ,称为x,父节点在当前节点和兄弟节点处进行x的替换,当前节点找合适位置(头或尾)进行x的添加,然后当前节点变成父节点,进入(4),兄弟节点key size <= key_min_size,进入(6)
(6)兄弟节点和当前节点合并,删除兄弟节点和两节点之间的父节点的key值,如果父节点是root且删除key之后,key size=0,则当前节点变成root,结束,否则当前节点变成父节点,进入(4)

[91]06:16:01[test][5864]        [BPTree<int,char>::erase]       remove key  _key:  5   (BPTree.h:164)
[92]06:16:01[debg][5864]        [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(5:E),(6:F),(7:G),(8:H),>   (BPTree.h:170)
[93]06:16:01[debg][5864]        [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(6:F),(7:G),(8:H),>   (BPTree.h:216)
[94]06:16:01[debg][5864]        [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 1:  getNodeInfo(_node):  <(6:F),(7:G),(8:H),>   (BPTree.h:232)
[95]06:16:01[test][5864]        [BPTree<int,char>::erase]       remove key  _key:  8   (BPTree.h:164)
[96]06:16:01[debg][5864]        [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(6:F),(7:G),(8:H),>   (BPTree.h:170)
[97]06:16:01[debg][5864]        [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(6:F),(7:G),>   (BPTree.h:216)
[98]06:16:01[debg][5864]        [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 1:  getNodeInfo(_node):  <(6:F),(7:G),>   (BPTree.h:232)
[99]06:16:01[test][5864]        [BPTree<int,char>::erase]       remove key  _key:  10   (BPTree.h:164)
[100]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(9:I),(10:J),(15:O),>   (BPTree.h:170)
[101]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(9:I),(15:O),>   (BPTree.h:216)
[102]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 1:  getNodeInfo(_node):  <(9:I),(15:O),>   (BPTree.h:232)
[103]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  15   (BPTree.h:164)
[104]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(9:I),(15:O),>   (BPTree.h:170)
[105]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(9:I),>   (BPTree.h:216)
[106]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 3,merge node to target_node:start:  getNodeInfo(_node):  <(9:I),>  getNodeInfo(parent):  <8,15,17,19,>  getNodeInfo(bro_node):  <(6:F),(7:G),>   (BPTree.h:300)
[107]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 3,merge node to target_node:result:  getNodeInfo(_node):  <(6:F),(7:G),(9:I),>  getNodeInfo(parent):  <15,17,19,>  getNodeInfo(bro_node):  <>   (BPTree.h:329)
[108]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <15,17,19,>   (BPTree.h:216)
[109]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  16   (BPTree.h:164)
[110]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(16:P),(17:Q),>   (BPTree.h:170)
[111]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(17:Q),>   (BPTree.h:216)
[112]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 2,bro split,start:  getNodeInfo(_node):  <(17:Q),>  getNodeInfo(parent):  <15,17,19,>  getNodeInfo(bro_node):  <(6:F),(7:G),(9:I),>  move_key:  9   (BPTree.h:269)
[113]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 2,bro split,result:  getNodeInfo(_node):  <(9:I),(17:Q),>  getNodeInfo(parent):  <7,17,19,>  getNodeInfo(bro_node):  <(6:F),(7:G),>  move_key:  9   (BPTree.h:294)
[114]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  17   (BPTree.h:164)
[115]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(9:I),(17:Q),>   (BPTree.h:170)
[116]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(9:I),>   (BPTree.h:216)
[117]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 3,merge node to target_node:start:  getNodeInfo(_node):  <(9:I),>  getNodeInfo(parent):  <7,17,19,>  getNodeInfo(bro_node):  <(6:F),(7:G),>   (BPTree.h:300)
[118]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 3,merge node to target_node:result:  getNodeInfo(_node):  <(6:F),(7:G),(9:I),>  getNodeInfo(parent):  <17,19,>  getNodeInfo(bro_node):  <>   (BPTree.h:329)
[119]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <17,19,>   (BPTree.h:216)
[120]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  18   (BPTree.h:164)
[121]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(18:R),(19:S),>   (BPTree.h:170)
[122]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(19:S),>   (BPTree.h:216)
[123]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 2,bro split,start:  getNodeInfo(_node):  <(19:S),>  getNodeInfo(parent):  <17,19,>  getNodeInfo(bro_node):  <(6:F),(7:G),(9:I),>  move_key:  9   (BPTree.h:269)
[124]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 2,bro split,result:  getNodeInfo(_node):  <(9:I),(19:S),>  getNodeInfo(parent):  <7,19,>  getNodeInfo(bro_node):  <(6:F),(7:G),>  move_key:  9   (BPTree.h:294)
[125]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  19   (BPTree.h:164)
[126]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(9:I),(19:S),>   (BPTree.h:170)
[127]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(9:I),>   (BPTree.h:216)
[128]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 2,bro split,start:  getNodeInfo(_node):  <(9:I),>  getNodeInfo(parent):  <7,19,>  getNodeInfo(bro_node):  <(20:T),(21:U),(22:V),>  move_key:  20   (BPTree.h:269)
[129]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 2,bro split,result:  getNodeInfo(_node):  <(9:I),(20:T),>  getNodeInfo(parent):  <7,20,>  getNodeInfo(bro_node):  <(21:U),(22:V),>  move_key:  20   (BPTree.h:294)
[130]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  20   (BPTree.h:164)
[131]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(9:I),(20:T),>   (BPTree.h:170)
[132]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(9:I),>   (BPTree.h:216)
[133]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 3,merge node to target_node:start:  getNodeInfo(_node):  <(9:I),>  getNodeInfo(parent):  <7,20,>  getNodeInfo(bro_node):  <(6:F),(7:G),>   (BPTree.h:300)
[134]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 3,merge node to target_node:result:  getNodeInfo(_node):  <(6:F),(7:G),(9:I),>  getNodeInfo(parent):  <20,>  getNodeInfo(bro_node):  <>   (BPTree.h:329)
[135]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <20,>   (BPTree.h:216)
[136]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  21   (BPTree.h:164)
[137]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(21:U),(22:V),>   (BPTree.h:170)
[138]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(22:V),>   (BPTree.h:216)
[139]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 2,bro split,start:  getNodeInfo(_node):  <(22:V),>  getNodeInfo(parent):  <20,>  getNodeInfo(bro_node):  <(6:F),(7:G),(9:I),>  move_key:  9   (BPTree.h:269)
[140]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 2,bro split,result:  getNodeInfo(_node):  <(9:I),(22:V),>  getNodeInfo(parent):  <7,>  getNodeInfo(bro_node):  <(6:F),(7:G),>  move_key:  9   (BPTree.h:294)
[141]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  22   (BPTree.h:164)
[142]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(9:I),(22:V),>   (BPTree.h:170)
[143]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(9:I),>   (BPTree.h:216)
[144]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 3,merge node to target_node:start:  getNodeInfo(_node):  <(9:I),>  getNodeInfo(parent):  <7,>  getNodeInfo(bro_node):  <(6:F),(7:G),>   (BPTree.h:300)
[145]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        case 3,merge node to target_node:result:  getNodeInfo(_node):  <(6:F),(7:G),(9:I),>  getNodeInfo(parent):  <>  getNodeInfo(bro_node):  <>   (BPTree.h:329)
[146]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  6   (BPTree.h:164)
[147]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(6:F),(7:G),(9:I),>   (BPTree.h:170)
[148]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(7:G),(9:I),>   (BPTree.h:216)
[149]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  9   (BPTree.h:164)
[150]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(7:G),(9:I),>   (BPTree.h:170)
[151]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <(7:G),>   (BPTree.h:216)
[152]06:16:01[test][5864]       [BPTree<int,char>::erase]       remove key  _key:  7   (BPTree.h:164)
[153]06:16:01[debg][5864]       [BPTree<int,char>::erase]       find  getNodeInfo(node_leaf):  <(7:G),>   (BPTree.h:170)
[154]06:16:01[debg][5864]       [BPTree<int,char>::adjustmentTreeNodeAfterErase]        start adjustment  getNodeInfo(_node):  <>   (BPTree.h:216)
[155]06:16:02[debg][5864]       [Start::doSomething]    values  tree is null   (Start.cpp:57)

删除
5,
请添加图片描述

8,
请添加图片描述

10,
请添加图片描述

15,
请添加图片描述

16,
请添加图片描述

17,
请添加图片描述

18,
请添加图片描述

19,
请添加图片描述

20,
请添加图片描述

21,
请添加图片描述

22,
请添加图片描述
6,
请添加图片描述

9,
请添加图片描述
7请添加图片描述

	//remove
	
	void erase(const_key_type_reference _key) {
		do {
			//0.judge exist key
			LOGXT("remove key", VAR_DATA(_key));
			auto [node_leaf, loc, is_find] = findProperLeaf(_key);
			if (is_find == false) {
				LOGXW("key no exist", VAR_DATA(_key));
				break;
			}
			LOGXD("find", VAR_DATA(getNodeInfo(node_leaf)));
			//1.delete key
			auto& keys = node_leaf->getKeys();
			keys.erase(keys.begin() + loc);
			auto& values = node_leaf->getValues();
			values.erase(values.begin() + loc);
			//2.adjustment tree
			adjustmentTreeNodeAfterErase(node_leaf);
 			
		} while (false);
	}
	size_type findNodeLocInParent(node_type_ptr _node) {
		size_type loc = -1;
		do {
			if (_node == nullptr)break;
			node_type_ptr parent = _node->getParent();
			if(parent==nullptr)break;
			auto parent_childs = parent->getChilds();
			for(size_type i=0;i<parent_childs.size();i++){
				if (parent_childs[i] == _node) {
					loc = i;
					break;
				}
			}

		} while (false);
		return loc;
	}
	std::tuple<node_type_ptr, size_type> findBroNode(node_type_ptr _node,bool _is_left=true) {
		node_type_ptr bro_node = nullptr;
		size_type parent_loc = -1;
		do {
			if (_node == nullptr)break;
			node_type_ptr parent = _node->getParent();
			if (parent == nullptr)break;
			size_type node_loc = findNodeLocInParent(_node);
			if (node_loc == -1)break;
			if (_is_left && node_loc == 0)break;
			if (_is_left == false && node_loc == parent->getChilds().size() - 1)break;
			parent_loc = _is_left ? node_loc - 1 : node_loc + 1;
			bro_node = parent->getChilds()[parent_loc];
		} while (false);
		return std::tuple(bro_node, parent_loc);
	}
	void adjustmentTreeNodeAfterErase(node_type_ptr _node) {
		do {
			LOGXD("start adjustment", VAR_DATA(getNodeInfo(_node)));
			if (_node == nullptr)break;
			auto& target_keys = _node->getKeys();
			node_type_ptr parent = _node->getParent();
			if (parent == nullptr) {
				if (getRoot() != _node) {
					LOGXF("tree have error");
				}
				if (target_keys.size() == 0) {
					delete _node;
					getRoot() = nullptr;
				}
				break;
			}
			//1.key size >= min size
			if (target_keys.size() >= getNodeMinSize()) {
				LOGXD("case 1:", VAR_DATA(getNodeInfo(_node)));
				break;
			}
			//2.find bro_node
			node_type_ptr left_bro_node = nullptr;
			size_type left_bro_node_loc = -1;
			node_type_ptr right_bro_node = nullptr;
			size_type right_bro_node_loc = -1;
			auto find_result = findBroNode(_node, true);
			left_bro_node = std::get<0>(find_result);
			left_bro_node_loc = std::get<1>(find_result);
			find_result = findBroNode(_node, false);
			right_bro_node = std::get<0>(find_result);
			right_bro_node_loc = std::get<1>(find_result);
			bool is_left_bro = left_bro_node?true:false;
			node_type_ptr bro_node = nullptr;
			if (left_bro_node && left_bro_node->getKeys().size() > getNodeMinSize()) {
				bro_node = left_bro_node;
				is_left_bro = true;
			}
			else if (right_bro_node && right_bro_node->getKeys().size() > getNodeMinSize()) {
				is_left_bro = false;
				bro_node = right_bro_node;
			}
			else {
				bro_node = is_left_bro ? left_bro_node : right_bro_node;
			}
			//3.if bro_node size > min_size ,can split key of x,parent replace x,target_node will add x
			auto& bro_keys = bro_node->getKeys();
			auto& parent_keys = parent->getKeys();
			if (bro_keys.size() > getNodeMinSize()) {
				//3.1 deal key
				size_type bro_split_loc = is_left_bro ? bro_keys.size() - 1 : 0;
				size_type parent_replace_loc = is_left_bro ? left_bro_node_loc : right_bro_node_loc - 1;
				size_type target_node_add_loc = is_left_bro ? 0 : target_keys.size();
				key_type move_key = bro_keys[bro_split_loc];
				LOGXD("case 2,bro split,start:", VAR_DATA(getNodeInfo(_node)), VAR_DATA(getNodeInfo(parent)),
					VAR_DATA(getNodeInfo(bro_node)), VAR_DATA(move_key));
				bro_keys.erase(bro_keys.begin() + bro_split_loc);
				parent_keys[parent_replace_loc] = move_key;
				if (is_left_bro)parent_keys[parent_replace_loc] = bro_keys[bro_split_loc - 1];
				//add this line, this will not same ,because find not same
				target_keys.insert(target_keys.begin() + target_node_add_loc, move_key);
				//3.2 deal value or child
				if (_node->isLeaf()) {
					auto& target_values = _node->getValues();
					auto& bro_values = bro_node->getValues();
					value_type move_value = bro_values[bro_split_loc];
					bro_values.erase(bro_values.begin() + bro_split_loc);
					target_values.insert(target_values.begin() + target_node_add_loc, move_value);
				}
				else {
					auto& target_childs = _node->getChilds();
					auto& bro_childs = bro_node->getChilds();
					size_type bro_split_child_loc = is_left_bro ? bro_childs.size()-1 : 0;
					size_type target_node_add_child_loc = is_left_bro ? 0 : target_childs.size();
					node_type_ptr move_child = bro_childs[bro_split_child_loc];
					bro_childs.erase(bro_childs.begin() + bro_split_child_loc);
					target_childs.insert(target_childs.begin() + target_node_add_child_loc, move_child);
					updataChildParent(_node);
				}
				LOGXD("case 2,bro split,result:", VAR_DATA(getNodeInfo(_node)), VAR_DATA(getNodeInfo(parent)),
					VAR_DATA(getNodeInfo(bro_node)), VAR_DATA(move_key));
				break;
			}
			//4.bro_key size is <=min_size, can merge bro_node to target_node
			{
				LOGXD("case 3,merge node to target_node:start:", VAR_DATA(getNodeInfo(_node)), VAR_DATA(getNodeInfo(parent)),
					VAR_DATA(getNodeInfo(bro_node)));
				size_type parent_erase_size = is_left_bro ? left_bro_node_loc : right_bro_node_loc - 1;
				size_type target_insert_loc = is_left_bro ? 0 : target_keys.size();
				parent_keys.erase(parent_keys.begin() + parent_erase_size);
				target_keys.insert(target_keys.begin()+target_insert_loc, bro_keys.begin(), bro_keys.end());
				bro_keys.clear();
				if (_node->isLeaf()) {
					auto& target_values = _node->getValues();
					auto& bro_values = bro_node->getValues();
					target_values.insert(target_values.begin()+target_insert_loc, 
						bro_values.begin(), bro_values.end());
					bro_values.clear();
				}
				else {
					auto& target_childs = _node->getChilds();
					auto& bro_childs = bro_node->getChilds();
					size_type target_insert_child_loc = is_left_bro ? 0 : target_childs.size();
					target_childs.insert(target_childs.begin()+target_insert_child_loc,
						bro_childs.begin(), bro_childs.end());
					bro_childs.clear();
				}

				size_type parent_erase_child_loc = is_left_bro ? left_bro_node_loc : right_bro_node_loc;
				auto& parent_childs = parent->getChilds();
				parent_childs.erase(parent_childs.begin() + parent_erase_child_loc);
				

				updataChildParent(_node);
				LOGXD("case 3,merge node to target_node:result:", VAR_DATA(getNodeInfo(_node)), VAR_DATA(getNodeInfo(parent)),
					VAR_DATA(getNodeInfo(bro_node)));
				delete bro_node;
				if (parent == getRoot()&&parent_keys.size()==0) {
					getRoot() = _node;
					getRoot()->getParent() = nullptr;
					delete parent;
					break;
				}
				adjustmentTreeNodeAfterErase(parent);
			}

		} while (false);
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值