当前位置:   article > 正文

B+树的Java实现_b+树java实现

b+树java实现

下面的B+树算法是在我学习了别人的代码之后经过修改完成的,主要在叶子节点上使用了二分查找,另外在更新节点上也减少了部分的递归操作,还对节点的结构做了细微的修改(每个节点得孩子指针比关键码多1,原来是孩子指针和关键码一样多,这也与B+树的原本定义一致),应该说整个程序的逻辑比原来清晰了一些。在此特别感谢wguoyong作者!大家可以参考原博主的代码点击打开链接

在写B+树的过程中,其实查询和插入操作都不算很难,最难的是删除操作,在做中间节点合并的时候需要特别注意关键字和孩子指针的更新,具体见代码。

    我对改进后的算法与之前的做了比较,下面的测试我在Macbook air  OS X 10.9.2上做的测试:

 

阶数10阶

修改前

修改后

随机插入100万条数据

4100ms

2200ms

顺序插入100万条数据

1800ms

940ms

随机查询100万次数据

2800ms

1350ms

顺序查询100万次数据

730ms

250ms

随机删除100万次数据

4600ms

1400ms

顺序删除100万次数据

20­­00ms

450ms

 

 

 

 阶数100阶

修改前

修改后

随机插入100万条数据

8100ms

2100ms

顺序插入100万条数据

4300ms

700ms

随机查询100万次数据

2000ms

1200ms

顺序查询100万次数据

850ms

250ms

随机删除100万次数据

8000ms

1500ms

顺序删除100万次数据

4500ms

300ms

 

源代码:

BplusTree.java


  1. /**
  2. * B+树的定义:
  3. *
  4. * 1.任意非叶子结点最多有M个子节点;且M>2;M为B+树的阶数
  5. * 2.除根结点以外的非叶子结点至少有 (M+1)/2个子节点;
  6. * 3.根结点至少有2个子节点;
  7. * 4.除根节点外每个结点存放至少(M-1)/2和至多M-1个关键字;(至少1个关键字)
  8. * 5.非叶子结点的子树指针比关键字多1个;
  9. * 6.非叶子节点的所有key按升序存放,假设节点的关键字分别为K[0], K[1] … K[M-2],
  10. * 指向子女的指针分别为P[0], P[1]…P[M-1]。则有:
  11. * P[0] < K[0] <= P[1] < K[1] …..< K[M-2] <= P[M-1]
  12. * 7.所有叶子结点位于同一层;
  13. * 8.为所有叶子结点增加一个链指针;
  14. * 9.所有关键字都在叶子结点出现
  15. */
  16. /**
  17. * @author LeeJay 2014-04-03
  18. *
  19. */
  20. import java.util.ArrayList;
  21. import java.util.List;
  22. import java.util.Random;
  23. public class BplusTree <K extends Comparable<K>, V>{
  24. /** 根节点 */
  25. protected BplusNode<K, V> root;
  26. /** 阶数,M值 */
  27. protected int order;
  28. /** 叶子节点的链表头 */
  29. protected BplusNode<K, V> head;
  30. /** 树高*/
  31. protected int height = 0;
  32. public BplusNode<K, V> getHead() {
  33. return head;
  34. }
  35. public void setHead(BplusNode<K, V> head) {
  36. this.head = head;
  37. }
  38. public BplusNode<K, V> getRoot() {
  39. return root;
  40. }
  41. public void setRoot(BplusNode<K, V> root) {
  42. this.root = root;
  43. }
  44. public int getOrder() {
  45. return order;
  46. }
  47. public void setOrder(int order) {
  48. this.order = order;
  49. }
  50. public void setHeight(int height) {
  51. this.height = height;
  52. }
  53. public int getHeight() {
  54. return height;
  55. }
  56. public V get(K key) {
  57. return root.get(key);
  58. }
  59. public V remove(K key) {
  60. return root.remove(key, this);
  61. }
  62. public void insertOrUpdate(K key, V value) {
  63. root.insertOrUpdate(key, value, this);
  64. }
  65. public BplusTree(int order) {
  66. if (order < 3) {
  67. System.out.print("order must be greater than 2");
  68. System.exit(0);
  69. }
  70. this.order = order;
  71. root = new BplusNode<K, V>(true, true);
  72. head = root;
  73. }
  74. // 测试
  75. public static void main(String[] args) {
  76. int size = 1000000;
  77. int order = 100;
  78. // testRandomInsert(size, order);
  79. //
  80. // testOrderInsert(size, order);
  81. //
  82. // testRandomSearch(size, order);
  83. //
  84. // testOrderSearch(size, order);
  85. //
  86. // testRandomRemove(size, order);
  87. //
  88. // testOrderRemove(size, order);
  89. }
  90. private static void testOrderRemove(int size, int order) {
  91. BplusTree<Integer, Integer> tree = new BplusTree<Integer, Integer>(order);
  92. System.out.println("\nTest order remove " + size + " datas, of order:"
  93. + order);
  94. System.out.println("Begin order insert...");
  95. for (int i = 0; i < size; i++) {
  96. tree.insertOrUpdate(i, i);
  97. }
  98. System.out.println("Begin order remove...");
  99. long current = System.currentTimeMillis();
  100. for (int j = 0; j < size; j++) {
  101. if (tree.remove(j) == null) {
  102. System.err.println("得不到数据:" + j);
  103. break;
  104. }
  105. }
  106. long duration = System.currentTimeMillis() - current;
  107. System.out.println("time elpsed for duration: " + duration);
  108. System.out.println(tree.getHeight());
  109. }
  110. private static void testRandomRemove(int size, int order) {
  111. BplusTree<Integer, Integer> tree = new BplusTree<Integer, Integer>(order);
  112. System.out.println("\nTest random remove " + size + " datas, of order:"
  113. + order);
  114. Random random = new Random();
  115. boolean[] a = new boolean[size + 10];
  116. List<Integer> list = new ArrayList<Integer>();
  117. int randomNumber = 0;
  118. System.out.println("Begin random insert...");
  119. for (int i = 0; i < size; i++) {
  120. randomNumber = random.nextInt(size);
  121. a[randomNumber] = true;
  122. list.add(randomNumber);
  123. tree.insertOrUpdate(randomNumber, randomNumber);
  124. }
  125. System.out.println("Begin random remove...");
  126. long current = System.currentTimeMillis();
  127. for (int j = 0; j < size; j++) {
  128. randomNumber = list.get(j);
  129. if (a[randomNumber]) {
  130. if (tree.remove(randomNumber) == null) {
  131. System.err.println("得不到数据:" + randomNumber);
  132. break;
  133. } else {
  134. a[randomNumber] = false;
  135. }
  136. }
  137. }
  138. long duration = System.currentTimeMillis() - current;
  139. System.out.println("time elpsed for duration: " + duration);
  140. System.out.println(tree.getHeight());
  141. }
  142. private static void testOrderSearch(int size, int order) {
  143. BplusTree<Integer, Integer> tree = new BplusTree<Integer, Integer>(order);
  144. System.out.println("\nTest order search " + size + " datas, of order:"
  145. + order);
  146. System.out.println("Begin order insert...");
  147. for (int i = 0; i < size; i++) {
  148. tree.insertOrUpdate(i, i);
  149. }
  150. System.out.println("Begin order search...");
  151. long current = System.currentTimeMillis();
  152. for (int j = 0; j < size; j++) {
  153. if (tree.get(j) == null) {
  154. System.err.println("得不到数据:" + j);
  155. break;
  156. }
  157. }
  158. long duration = System.currentTimeMillis() - current;
  159. System.out.println("time elpsed for duration: " + duration);
  160. }
  161. private static void testRandomSearch(int size, int order) {
  162. BplusTree<Integer, Integer> tree = new BplusTree<Integer, Integer>(order);
  163. System.out.println("\nTest random search " + size + " datas, of order:"
  164. + order);
  165. Random random = new Random();
  166. boolean[] a = new boolean[size + 10];
  167. int randomNumber = 0;
  168. System.out.println("Begin random insert...");
  169. for (int i = 0; i < size; i++) {
  170. randomNumber = random.nextInt(size);
  171. a[randomNumber] = true;
  172. tree.insertOrUpdate(randomNumber, randomNumber);
  173. }
  174. System.out.println("Begin random search...");
  175. long current = System.currentTimeMillis();
  176. for (int j = 0; j < size; j++) {
  177. randomNumber = random.nextInt(size);
  178. if (a[randomNumber]) {
  179. if (tree.get(randomNumber) == null) {
  180. System.err.println("得不到数据:" + randomNumber);
  181. break;
  182. }
  183. }
  184. }
  185. long duration = System.currentTimeMillis() - current;
  186. System.out.println("time elpsed for duration: " + duration);
  187. }
  188. private static void testRandomInsert(int size, int order) {
  189. BplusTree<Integer, Integer> tree = new BplusTree<Integer, Integer>(order);
  190. System.out.println("\nTest random insert " + size + " datas, of order:"
  191. + order);
  192. Random random = new Random();
  193. int randomNumber = 0;
  194. long current = System.currentTimeMillis();
  195. for (int i = 0; i < size; i++) {
  196. randomNumber = random.nextInt(size);
  197. tree.insertOrUpdate(randomNumber, randomNumber);
  198. }
  199. long duration = System.currentTimeMillis() - current;
  200. System.out.println("time elpsed for duration: " + duration);
  201. System.out.println(tree.getHeight());
  202. }
  203. private static void testOrderInsert(int size, int order) {
  204. BplusTree<Integer, Integer> tree = new BplusTree<Integer, Integer>(order);
  205. System.out.println("\nTest order insert " + size + " datas, of order:"
  206. + order);
  207. long current = System.currentTimeMillis();
  208. for (int i = 0; i < size; i++) {
  209. tree.insertOrUpdate(i, i);
  210. }
  211. long duration = System.currentTimeMillis() - current;
  212. System.out.println("time elpsed for duration: " + duration);
  213. }
  214. }


BplusNode.java

  1. import java.util.AbstractMap.SimpleEntry;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import java.util.Map.Entry;
  5. public class BplusNode <K extends Comparable<K>, V> {
  6. /** 是否为叶子节点 */
  7. protected boolean isLeaf;
  8. /** 是否为根节点*/
  9. protected boolean isRoot;
  10. /** 父节点 */
  11. protected BplusNode<K, V> parent;
  12. /** 叶节点的前节点*/
  13. protected BplusNode<K, V> previous;
  14. /** 叶节点的后节点*/
  15. protected BplusNode<K, V> next;
  16. /** 节点的关键字 */
  17. protected List<Entry<K, V>> entries;
  18. /** 子节点 */
  19. protected List<BplusNode<K, V>> children;
  20. public BplusNode(boolean isLeaf) {
  21. this.isLeaf = isLeaf;
  22. entries = new ArrayList<Entry<K, V>>();
  23. if (!isLeaf) {
  24. children = new ArrayList<BplusNode<K, V>>();
  25. }
  26. }
  27. public BplusNode(boolean isLeaf, boolean isRoot) {
  28. this(isLeaf);
  29. this.isRoot = isRoot;
  30. }
  31. public V get(K key) {
  32. //如果是叶子节点
  33. if (isLeaf) {
  34. int low = 0, high = entries.size() - 1, mid;
  35. int comp ;
  36. while (low <= high) {
  37. mid = (low + high) / 2;
  38. comp = entries.get(mid).getKey().compareTo(key);
  39. if (comp == 0) {
  40. return entries.get(mid).getValue();
  41. } else if (comp < 0) {
  42. low = mid + 1;
  43. } else {
  44. high = mid - 1;
  45. }
  46. }
  47. //未找到所要查询的对象
  48. return null;
  49. }
  50. //如果不是叶子节点
  51. //如果key小于节点最左边的key,沿第一个子节点继续搜索
  52. if (key.compareTo(entries.get(0).getKey()) < 0) {
  53. return children.get(0).get(key);
  54. //如果key大于等于节点最右边的key,沿最后一个子节点继续搜索
  55. }else if (key.compareTo(entries.get(entries.size()-1).getKey()) >= 0) {
  56. return children.get(children.size()-1).get(key);
  57. //否则沿比key大的前一个子节点继续搜索
  58. }else {
  59. int low = 0, high = entries.size() - 1, mid= 0;
  60. int comp ;
  61. while (low <= high) {
  62. mid = (low + high) / 2;
  63. comp = entries.get(mid).getKey().compareTo(key);
  64. if (comp == 0) {
  65. return children.get(mid+1).get(key);
  66. } else if (comp < 0) {
  67. low = mid + 1;
  68. } else {
  69. high = mid - 1;
  70. }
  71. }
  72. return children.get(low).get(key);
  73. }
  74. }
  75. public void insertOrUpdate(K key, V value, BplusTree<K,V> tree){
  76. //如果是叶子节点
  77. if (isLeaf){
  78. //不需要分裂,直接插入或更新
  79. if (contains(key) != -1 || entries.size() < tree.getOrder()){
  80. insertOrUpdate(key, value);
  81. if(tree.getHeight() == 0){
  82. tree.setHeight(1);
  83. }
  84. return ;
  85. }
  86. //需要分裂
  87. //分裂成左右两个节点
  88. BplusNode<K,V> left = new BplusNode<K,V>(true);
  89. BplusNode<K,V> right = new BplusNode<K,V>(true);
  90. //设置链接
  91. if (previous != null){
  92. previous.next = left;
  93. left.previous = previous ;
  94. }
  95. if (next != null) {
  96. next.previous = right;
  97. right.next = next;
  98. }
  99. if (previous == null){
  100. tree.setHead(left);
  101. }
  102. left.next = right;
  103. right.previous = left;
  104. previous = null;
  105. next = null;
  106. //复制原节点关键字到分裂出来的新节点
  107. copy2Nodes(key, value, left, right, tree);
  108. //如果不是根节点
  109. if (parent != null) {
  110. //调整父子节点关系
  111. int index = parent.children.indexOf(this);
  112. parent.children.remove(this);
  113. left.parent = parent;
  114. right.parent = parent;
  115. parent.children.add(index,left);
  116. parent.children.add(index + 1, right);
  117. parent.entries.add(index,right.entries.get(0));
  118. entries = null; //删除当前节点的关键字信息
  119. children = null; //删除当前节点的孩子节点引用
  120. //父节点插入或更新关键字
  121. parent.updateInsert(tree);
  122. parent = null; //删除当前节点的父节点引用
  123. //如果是根节点
  124. }else {
  125. isRoot = false;
  126. BplusNode<K,V> parent = new BplusNode<K,V> (false, true);
  127. tree.setRoot(parent);
  128. left.parent = parent;
  129. right.parent = parent;
  130. parent.children.add(left);
  131. parent.children.add(right);
  132. parent.entries.add(right.entries.get(0));
  133. entries = null;
  134. children = null;
  135. }
  136. return ;
  137. }
  138. //如果不是叶子节点
  139. //如果key小于等于节点最左边的key,沿第一个子节点继续搜索
  140. if (key.compareTo(entries.get(0).getKey()) < 0) {
  141. children.get(0).insertOrUpdate(key, value, tree);
  142. //如果key大于节点最右边的key,沿最后一个子节点继续搜索
  143. }else if (key.compareTo(entries.get(entries.size()-1).getKey()) >= 0) {
  144. children.get(children.size()-1).insertOrUpdate(key, value, tree);
  145. //否则沿比key大的前一个子节点继续搜索
  146. }else {
  147. int low = 0, high = entries.size() - 1, mid= 0;
  148. int comp ;
  149. while (low <= high) {
  150. mid = (low + high) / 2;
  151. comp = entries.get(mid).getKey().compareTo(key);
  152. if (comp == 0) {
  153. children.get(mid+1).insertOrUpdate(key, value, tree);
  154. break;
  155. } else if (comp < 0) {
  156. low = mid + 1;
  157. } else {
  158. high = mid - 1;
  159. }
  160. }
  161. if(low>high){
  162. children.get(low).insertOrUpdate(key, value, tree);
  163. }
  164. }
  165. }
  166. private void copy2Nodes(K key, V value, BplusNode<K,V> left,
  167. BplusNode<K,V> right,BplusTree<K,V> tree) {
  168. //左右两个节点关键字长度
  169. int leftSize = (tree.getOrder() + 1) / 2 + (tree.getOrder() + 1) % 2;
  170. boolean b = false;//用于记录新元素是否已经被插入
  171. for (int i = 0; i < entries.size(); i++) {
  172. if(leftSize !=0){
  173. leftSize --;
  174. if(!b&&entries.get(i).getKey().compareTo(key) > 0){
  175. left.entries.add(new SimpleEntry<K, V>(key, value));
  176. b = true;
  177. i--;
  178. }else {
  179. left.entries.add(entries.get(i));
  180. }
  181. }else {
  182. if(!b&&entries.get(i).getKey().compareTo(key) > 0){
  183. right.entries.add(new SimpleEntry<K, V>(key, value));
  184. b = true;
  185. i--;
  186. }else {
  187. right.entries.add(entries.get(i));
  188. }
  189. }
  190. }
  191. if(!b){
  192. right.entries.add(new SimpleEntry<K, V>(key, value));
  193. }
  194. }
  195. /** 插入节点后中间节点的更新 */
  196. protected void updateInsert(BplusTree<K,V> tree){
  197. //如果子节点数超出阶数,则需要分裂该节点
  198. if (children.size() > tree.getOrder()) {
  199. //分裂成左右两个节点
  200. BplusNode<K, V> left = new BplusNode<K, V>(false);
  201. BplusNode<K, V> right = new BplusNode<K, V>(false);
  202. //左右两个节点子节点的长度
  203. int leftSize = (tree.getOrder() + 1) / 2 + (tree.getOrder() + 1) % 2;
  204. int rightSize = (tree.getOrder() + 1) / 2;
  205. //复制子节点到分裂出来的新节点,并更新关键字
  206. for (int i = 0; i < leftSize; i++){
  207. left.children.add(children.get(i));
  208. children.get(i).parent = left;
  209. }
  210. for (int i = 0; i < rightSize; i++){
  211. right.children.add(children.get(leftSize + i));
  212. children.get(leftSize + i).parent = right;
  213. }
  214. for (int i = 0; i < leftSize - 1; i++) {
  215. left.entries.add(entries.get(i));
  216. }
  217. for (int i = 0; i < rightSize - 1; i++) {
  218. right.entries.add(entries.get(leftSize + i));
  219. }
  220. //如果不是根节点
  221. if (parent != null) {
  222. //调整父子节点关系
  223. int index = parent.children.indexOf(this);
  224. parent.children.remove(this);
  225. left.parent = parent;
  226. right.parent = parent;
  227. parent.children.add(index,left);
  228. parent.children.add(index + 1, right);
  229. parent.entries.add(index,entries.get(leftSize - 1));
  230. entries = null;
  231. children = null;
  232. //父节点更新关键字
  233. parent.updateInsert(tree);
  234. parent = null;
  235. //如果是根节点
  236. }else {
  237. isRoot = false;
  238. BplusNode<K, V> parent = new BplusNode<K, V>(false, true);
  239. tree.setRoot(parent);
  240. tree.setHeight(tree.getHeight() + 1);
  241. left.parent = parent;
  242. right.parent = parent;
  243. parent.children.add(left);
  244. parent.children.add(right);
  245. parent.entries.add(entries.get(leftSize - 1));
  246. entries = null;
  247. children = null;
  248. }
  249. }
  250. }
  251. /** 删除节点后中间节点的更新*/
  252. protected void updateRemove(BplusTree<K,V> tree) {
  253. // 如果子节点数小于M / 2或者小于2,则需要合并节点
  254. if (children.size() < tree.getOrder() / 2 || children.size() < 2) {
  255. if (isRoot) {
  256. // 如果是根节点并且子节点数大于等于2,OK
  257. if (children.size() >= 2) return;
  258. // 否则与子节点合并
  259. BplusNode<K, V> root = children.get(0);
  260. tree.setRoot(root);
  261. tree.setHeight(tree.getHeight() - 1);
  262. root.parent = null;
  263. root.isRoot = true;
  264. entries = null;
  265. children = null;
  266. return ;
  267. }
  268. //计算前后节点
  269. int currIdx = parent.children.indexOf(this);
  270. int prevIdx = currIdx - 1;
  271. int nextIdx = currIdx + 1;
  272. BplusNode<K, V> previous = null, next = null;
  273. if (prevIdx >= 0) {
  274. previous = parent.children.get(prevIdx);
  275. }
  276. if (nextIdx < parent.children.size()) {
  277. next = parent.children.get(nextIdx);
  278. }
  279. // 如果前节点子节点数大于M / 2并且大于2,则从其处借补
  280. if (previous != null
  281. && previous.children.size() > tree.getOrder() / 2
  282. && previous.children.size() > 2) {
  283. //前叶子节点末尾节点添加到首位
  284. int idx = previous.children.size() - 1;
  285. BplusNode<K, V> borrow = previous.children.get(idx);
  286. previous.children.remove(idx);
  287. borrow.parent = this;
  288. children.add(0, borrow);
  289. int preIndex = parent.children.indexOf(previous);
  290. entries.add(0,parent.entries.get(preIndex));
  291. parent.entries.set(preIndex, previous.entries.remove(idx - 1));
  292. return ;
  293. }
  294. // 如果后节点子节点数大于M / 2并且大于2,则从其处借补
  295. if (next != null
  296. && next.children.size() > tree.getOrder() / 2
  297. && next.children.size() > 2) {
  298. //后叶子节点首位添加到末尾
  299. BplusNode<K, V> borrow = next.children.get(0);
  300. next.children.remove(0);
  301. borrow.parent = this;
  302. children.add(borrow);
  303. int preIndex = parent.children.indexOf(this);
  304. entries.add(parent.entries.get(preIndex));
  305. parent.entries.set(preIndex, next.entries.remove(0));
  306. return ;
  307. }
  308. // 同前面节点合并
  309. if (previous != null
  310. && (previous.children.size() <= tree.getOrder() / 2
  311. || previous.children.size() <= 2)) {
  312. for (int i = 0; i < children.size(); i++) {
  313. previous.children.add(children.get(i));
  314. }
  315. for(int i = 0; i < previous.children.size();i++){
  316. previous.children.get(i).parent = this;
  317. }
  318. int indexPre = parent.children.indexOf(previous);
  319. previous.entries.add(parent.entries.get(indexPre));
  320. for (int i = 0; i < entries.size(); i++) {
  321. previous.entries.add(entries.get(i));
  322. }
  323. children = previous.children;
  324. entries = previous.entries;
  325. //更新父节点的关键字列表
  326. parent.children.remove(previous);
  327. previous.parent = null;
  328. previous.children = null;
  329. previous.entries = null;
  330. parent.entries.remove(parent.children.indexOf(this));
  331. if((!parent.isRoot
  332. && (parent.children.size() >= tree.getOrder() / 2
  333. && parent.children.size() >= 2))
  334. ||parent.isRoot && parent.children.size() >= 2){
  335. return ;
  336. }
  337. parent.updateRemove(tree);
  338. return ;
  339. }
  340. // 同后面节点合并
  341. if (next != null
  342. && (next.children.size() <= tree.getOrder() / 2
  343. || next.children.size() <= 2)) {
  344. for (int i = 0; i < next.children.size(); i++) {
  345. BplusNode<K, V> child = next.children.get(i);
  346. children.add(child);
  347. child.parent = this;
  348. }
  349. int index = parent.children.indexOf(this);
  350. entries.add(parent.entries.get(index));
  351. for (int i = 0; i < next.entries.size(); i++) {
  352. entries.add(next.entries.get(i));
  353. }
  354. parent.children.remove(next);
  355. next.parent = null;
  356. next.children = null;
  357. next.entries = null;
  358. parent.entries.remove(parent.children.indexOf(this));
  359. if((!parent.isRoot && (parent.children.size() >= tree.getOrder() / 2
  360. && parent.children.size() >= 2))
  361. ||parent.isRoot && parent.children.size() >= 2){
  362. return ;
  363. }
  364. parent.updateRemove(tree);
  365. return ;
  366. }
  367. }
  368. }
  369. public V remove(K key, BplusTree<K,V> tree){
  370. //如果是叶子节点
  371. if (isLeaf){
  372. //如果不包含该关键字,则直接返回
  373. if (contains(key) == -1){
  374. return null;
  375. }
  376. //如果既是叶子节点又是根节点,直接删除
  377. if (isRoot) {
  378. if(entries.size() == 1){
  379. tree.setHeight(0);
  380. }
  381. return remove(key);
  382. }
  383. //如果关键字数大于M / 2,直接删除
  384. if (entries.size() > tree.getOrder() / 2 && entries.size() > 2) {
  385. return remove(key);
  386. }
  387. //如果自身关键字数小于M / 2,并且前节点关键字数大于M / 2,则从其处借补
  388. if (previous != null &&
  389. previous.parent == parent
  390. && previous.entries.size() > tree.getOrder() / 2
  391. && previous.entries.size() > 2 ) {
  392. //添加到首位
  393. int size = previous.entries.size();
  394. entries.add(0, previous.entries.remove(size - 1));
  395. int index = parent.children.indexOf(previous);
  396. parent.entries.set(index, entries.get(0));
  397. return remove(key);
  398. }
  399. //如果自身关键字数小于M / 2,并且后节点关键字数大于M / 2,则从其处借补
  400. if (next != null
  401. && next.parent == parent
  402. && next.entries.size() > tree.getOrder() / 2
  403. && next.entries.size() > 2) {
  404. entries.add(next.entries.remove(0));
  405. int index = parent.children.indexOf(this);
  406. parent.entries.set(index, next.entries.get(0));
  407. return remove(key);
  408. }
  409. //同前面节点合并
  410. if (previous != null
  411. && previous.parent == parent
  412. && (previous.entries.size() <= tree.getOrder() / 2
  413. || previous.entries.size() <= 2)) {
  414. V returnValue = remove(key);
  415. for (int i = 0; i < entries.size(); i++) {
  416. //将当前节点的关键字添加到前节点的末尾
  417. previous.entries.add(entries.get(i));
  418. }
  419. entries = previous.entries;
  420. parent.children.remove(previous);
  421. previous.parent = null;
  422. previous.entries = null;
  423. //更新链表
  424. if (previous.previous != null) {
  425. BplusNode<K, V> temp = previous;
  426. temp.previous.next = this;
  427. previous = temp.previous;
  428. temp.previous = null;
  429. temp.next = null;
  430. }else {
  431. tree.setHead(this);
  432. previous.next = null;
  433. previous = null;
  434. }
  435. parent.entries.remove(parent.children.indexOf(this));
  436. if((!parent.isRoot && (parent.children.size() >= tree.getOrder() / 2
  437. && parent.children.size() >= 2))
  438. ||parent.isRoot && parent.children.size() >= 2){
  439. return returnValue;
  440. }
  441. parent.updateRemove(tree);
  442. return returnValue;
  443. }
  444. //同后面节点合并
  445. if(next != null
  446. && next.parent == parent
  447. && (next.entries.size() <= tree.getOrder() / 2
  448. || next.entries.size() <= 2)) {
  449. V returnValue = remove(key);
  450. for (int i = 0; i < next.entries.size(); i++) {
  451. //从首位开始添加到末尾
  452. entries.add(next.entries.get(i));
  453. }
  454. next.parent = null;
  455. next.entries = null;
  456. parent.children.remove(next);
  457. //更新链表
  458. if (next.next != null) {
  459. BplusNode<K, V> temp = next;
  460. temp.next.previous = this;
  461. next = temp.next;
  462. temp.previous = null;
  463. temp.next = null;
  464. }else {
  465. next.previous = null;
  466. next = null;
  467. }
  468. //更新父节点的关键字列表
  469. parent.entries.remove(parent.children.indexOf(this));
  470. if((!parent.isRoot && (parent.children.size() >= tree.getOrder() / 2
  471. && parent.children.size() >= 2))
  472. ||parent.isRoot && parent.children.size() >= 2){
  473. return returnValue;
  474. }
  475. parent.updateRemove(tree);
  476. return returnValue;
  477. }
  478. }
  479. /*如果不是叶子节点*/
  480. //如果key小于等于节点最左边的key,沿第一个子节点继续搜索
  481. if (key.compareTo(entries.get(0).getKey()) < 0) {
  482. return children.get(0).remove(key, tree);
  483. //如果key大于节点最右边的key,沿最后一个子节点继续搜索
  484. }else if (key.compareTo(entries.get(entries.size()-1).getKey()) >= 0) {
  485. return children.get(children.size()-1).remove(key, tree);
  486. //否则沿比key大的前一个子节点继续搜索
  487. }else {
  488. int low = 0, high = entries.size() - 1, mid= 0;
  489. int comp ;
  490. while (low <= high) {
  491. mid = (low + high) / 2;
  492. comp = entries.get(mid).getKey().compareTo(key);
  493. if (comp == 0) {
  494. return children.get(mid + 1).remove(key, tree);
  495. } else if (comp < 0) {
  496. low = mid + 1;
  497. } else {
  498. high = mid - 1;
  499. }
  500. }
  501. return children.get(low).remove(key, tree);
  502. }
  503. }
  504. /** 判断当前节点是否包含该关键字*/
  505. protected int contains(K key) {
  506. int low = 0, high = entries.size() - 1, mid;
  507. int comp ;
  508. while (low <= high) {
  509. mid = (low + high) / 2;
  510. comp = entries.get(mid).getKey().compareTo(key);
  511. if (comp == 0) {
  512. return mid;
  513. } else if (comp < 0) {
  514. low = mid + 1;
  515. } else {
  516. high = mid - 1;
  517. }
  518. }
  519. return -1;
  520. }
  521. /** 插入到当前节点的关键字中*/
  522. protected void insertOrUpdate(K key, V value){
  523. //二叉查找,插入
  524. int low = 0, high = entries.size() - 1, mid;
  525. int comp ;
  526. while (low <= high) {
  527. mid = (low + high) / 2;
  528. comp = entries.get(mid).getKey().compareTo(key);
  529. if (comp == 0) {
  530. entries.get(mid).setValue(value);
  531. break;
  532. } else if (comp < 0) {
  533. low = mid + 1;
  534. } else {
  535. high = mid - 1;
  536. }
  537. }
  538. if(low>high){
  539. entries.add(low, new SimpleEntry<K, V>(key, value));
  540. }
  541. }
  542. /** 删除节点*/
  543. protected V remove(K key){
  544. int low = 0,high = entries.size() -1,mid;
  545. int comp;
  546. while(low<= high){
  547. mid = (low+high)/2;
  548. comp = entries.get(mid).getKey().compareTo(key);
  549. if(comp == 0){
  550. return entries.remove(mid).getValue();
  551. }else if(comp < 0){
  552. low = mid + 1;
  553. }else {
  554. high = mid - 1;
  555. }
  556. }
  557. return null;
  558. }
  559. public String toString(){
  560. StringBuilder sb = new StringBuilder();
  561. sb.append("isRoot: ");
  562. sb.append(isRoot);
  563. sb.append(", ");
  564. sb.append("isLeaf: ");
  565. sb.append(isLeaf);
  566. sb.append(", ");
  567. sb.append("keys: ");
  568. for (Entry<K,V> entry : entries){
  569. sb.append(entry.getKey());
  570. sb.append(", ");
  571. }
  572. sb.append(", ");
  573. return sb.toString();
  574. }
  575. }



声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Li_阴宅/article/detail/1007038
推荐阅读
相关标签
  

闽ICP备14008679号