编程内功修炼之数据结构—BTree(三)总结

BTree必须通过各种编程约束,使得不脱离BTree的本身特性;

1)BTree关键字插入操作;插入过程中,如果节点关键字达到上限,添加分裂约束,从而控制每个节点的关键字数维持在 t-1~2*t-1内;

2)BTree节点中的关键字查询;因为关键字按非降序进行排列,所以可以采用二分查找方法进行查询,以提高算法性能;

3)BTree关键字删除操作;

 删除操作必须保证节点关键字数n[x]>=t,这样删除一个关键字才不会违反BTree规则。

   当前节点是叶节点,可以直接删除;

   当前节点是内节点,可以寻找左右子女节点进行关键字替代;

   当前节点不足t方案:

    (a)如果当前节点关键字不足t,可以向兄弟节点进行借取;

         (b)如果左右相近兄弟节点都不满足>=t要求,那么可以采用合并方式;

   Delete实现方法如下:

  1 public void delete(BTreeNode node, Integer key){

  2         //删除关键字时,必须保证关键字大于等于t

  3         assert node.size() >=t || node == root;

  4         

  5         //对当前节点进行二分查找

  6         ResultSearch resultSearch = divideSearch(node.getKeys(), key);

  7         

  8         //成功

  9         if(resultSearch.result){

 10             

 11             //如果当前节点属于叶子节点,可以直接进行删除

 12             if(node.isLeaf()){

 13                 node.getKeys().remove(resultSearch.index.intValue());

 14             }else{

 15                 //如果不是叶子节点 ,判断前于key子节点状态

 16                 BTreeNode leftChildNode = node.childAt(resultSearch.index);

 17                 if(leftChildNode.size() >= t){

 18                     

 19                     //从leftChildNode进行借值 代替当前需要删除的关键字

 20                     //删除当前节点关键字

 21                     node.getKeys().remove(resultSearch.index.intValue());

 22                     node.insertKey(leftChildNode.keyAt(leftChildNode.size()-1), resultSearch.index);

 23                     delete(leftChildNode, leftChildNode.keyAt(leftChildNode.size()-1));

 24                 }else{

 25                     

 26                     BTreeNode rightChildNode = node.childAt(resultSearch.index + 1);

 27                     if(rightChildNode.size() >= t){

 28                         

 29                         //从rightChildNode进行借值 代替当前需要删除的关键字

 30                         node.getKeys().remove(resultSearch.index.intValue());

 31                         node.insertKey(rightChildNode.keyAt(0), resultSearch.index);

 32                         delete(rightChildNode, rightChildNode.keyAt(0));

 33                     }else{

 34                         

 35                         //对于索引的左右子节点的数量都等于t-1

 36                         //合适进行合并

 37                         //1.将父节点删除  将节点右子节点删除

 38                         node.getKeys().remove(resultSearch.index.intValue());

 39                         node.getChildrens().remove(resultSearch.index.intValue() + 1);

 40                         //2.将父节点添加到左子节点上

 41                         leftChildNode.getKeys().add(key);

 42                         //3.将删除的右子节点添加到左子节点上

 43                         for(int i=0 ; i<rightChildNode.size() ; i++){

 44                             leftChildNode.getKeys().add(rightChildNode.getKeys().get(i));

 45                         }

 46                         //如果右子节点非叶子节点,需要将其子女继承到左节点之下

 47                         if(!rightChildNode.isLeaf()){

 48                             for(int k=0 ; k<=rightChildNode.size() ; k++){

 49                                 leftChildNode.getChildrens().add(rightChildNode.childAt(k));

 50                             }

 51                         }

 52                         //递归删除

 53                         delete(leftChildNode, key);

 54                         

 55                     }

 56                 }

 57                 

 58             }

 59             

 60         }else{ //失败

 61             if(node.isLeaf()){

 62                 //不存在删除的对象

 63                 System.out.println("不存在删除的对象");

 64                 return ;

 65             }

 66             

 67             //获取子节点

 68             BTreeNode childNode = node.childAt(resultSearch.index);

 69             

 70             if(root == node && node.size()==0){

 71                 root = childNode;

 72             }

 73             

 74             if(childNode.size() >= t){   //如果满足递归条件

 75                 delete(childNode, key);

 76             }else{

 77                 //不满足size == t

 78                 //采取借关键字手段

 79                 

 80                 BTreeNode subNode = null;

 81                 int subIndex = 0;

 82                 //先检测右兄弟节点

 83                 if(resultSearch.index < node.size()){

 84                     if(node.childAt(resultSearch.index+1).size() >=t){

 85                         subNode  = node.childAt(resultSearch.index+1);

 86                         subIndex = resultSearch.index + 1;

 87                     }

 88                 }

 89                 //测试左兄弟节点

 90                 if(subNode == null){

 91                     if(resultSearch.index > 0){

 92                         if(node.childAt(resultSearch.index-1).size() >= t){

 93                             subNode  = node.childAt(resultSearch.index-1);

 94                             subIndex = resultSearch.index - 1;

 95                         }

 96                     }

 97                 }

 98                 //测试完成后

 99                 if(subNode != null){  //存在兄弟节点大于等于t情况

100                     //判断节点

101                     if(subIndex > resultSearch.index){ //右兄弟

102                         

103                         //将右关键字插入自身

104                         childNode.insertKey(node.keyAt(subIndex - 1), childNode.size());

105                         node.getKeys().remove(subIndex - 1);

106                         node.insertKey(subNode.keyAt(0), subIndex - 1);

107                         subNode.getKeys().remove(0);

108                         

109                         //右兄弟非子叶节点,则带有孩子节点

110                         if(!subNode.isLeaf()){

111                             childNode.getChildrens().add(subNode.getChildrens().get(0));

112                             subNode.getChildrens().remove(0);

113                         }

114                         

115                     }else{  //左兄弟

116                         

117                         //将左关键字插入自身最前位置

118                         childNode.insertKey(node.keyAt(subIndex), 0);

119                         node.getKeys().remove(subIndex);

120                         node.insertKey(subNode.keyAt(subNode.size()-1), subIndex);

121                         subNode.getKeys().remove(subNode.size()-1);

122                         

123                         //如果左兄弟非子叶节点

124                         if(!subNode.isLeaf()){

125                             childNode.insertChild(subNode.childAt(subNode.size()), 0);

126                             subNode.getChildrens().remove(subNode.size()-1);

127                         }    

128                     }

129                     delete(childNode, key);

130                     

131                 }else{

132                     

133                     //该节点的左右兄弟节点关键字都为t-1

134                     //选择合并方案

135                     if(resultSearch.index < node.size()){   //右兄弟存在

136                         

137                         subNode = node.childAt(resultSearch.index + 1);

138                         

139                         //childNode.getKeys().add(node.keyAt(resultSearch.index + 1));

140                         childNode.getKeys().add(node.keyAt(resultSearch.index));

141                         

142                         node.getKeys().remove(resultSearch.index.intValue());

143                         node.getChildrens().remove(resultSearch.index.intValue());

144                         

145                         for(int i=0 ; i<subNode.size() ; i++){

146                             childNode.getKeys().add(subNode.keyAt(i));

147                         }

148                         

149                         if(!subNode.isLeaf()){

150                             for(int k=0 ; k<=subNode.size(); k++){

151                                 childNode.getChildrens().add(subNode.childAt(k));

152                             }

153                         }

154                         

155                     }else{      //左兄弟存在

156                         

157                         subNode = node.childAt(resultSearch.index - 1);

158                         childNode.insertKey(node.keyAt(resultSearch.index-1), 0);

159                         node.getKeys().remove(resultSearch.index - 1);

160                         node.getChildrens().remove(resultSearch.index-1);

161                         

162                         for(int i=subNode.size()-1 ; i>=0 ; --i){

163                             childNode.insertKey(subNode.keyAt(i), 0);

164                         }

165                         

166                         if(!subNode.isLeaf()){

167                             for(int k=subNode.size() ; k>=0 ; --k){

168                                 childNode.insertChild(subNode.childAt(k),0);

169                             }

170                         }

171                         

172                     }

173                     if(root == node && node.size() == 0){

174                         root = childNode;

175                     }

176                     delete(childNode, key);

177                 }

178             }

179             

180         }

181     }

 

你可能感兴趣的:(数据结构)