1. 程式人生 > >b樹的實現(2)---java版程式碼

b樹的實現(2)---java版程式碼

原文地址: http://blog.csdn.net/cdnight/article/details/10619599

[java] view plain copy print?
  1. 感覺上,b樹的插入及刪除操作都不如RB樹複雜。當年插紅黑樹的各種操作解釋文章都不下幾十篇了,資料結構及演算法的除錯正確執行是一個大問題,因為錯誤往往出現在細微處。  
[java] view plain copy print? [java] view plain copy print? [java] view plain copy print?
  1. package BTree;  
  2. publicclass indexUnit {  
  3.     publicfloat indexNo;  
  4.     public  Object indexValue=new Object();  
  5. }  

[java] view plain copy print?
  1. package BTree;  
  2. import java.util.ArrayList;  
  3. publicclass TreeUnit {  
  4.     public TreeUnit _parent=null;  
  5.     public ArrayList<indexUnit> keys=new ArrayList<indexUnit>();  
  6.     public ArrayList<TreeUnit> childNodes=new ArrayList<TreeUnit>();  
  7. }  

[java] view plain copy print?
  1. package BTree;  
  2. /** 
  3.  * Created with IntelliJ IDEA. 
  4.  * User: Administrator 
  5.  * Date: 13-8-19 
  6.  * Time: 上午10:21 
  7.  * To change this template use File | Settings | File Templates. 
  8.  */
  9. public
    class BtreeGen {  
  10.     public TreeUnit _btreeRootNode=new TreeUnit();  
  11.     /* 
  12.      * 請注意,這個是最多容納的子樹的階,b樹的階應該是最多的子樹數量, 
  13.      * 根據b樹的性質,最大主鍵數量+1=最多子樹數量。 
  14.      * 並且,任何時刻,主鍵的數量比下屬子樹數量少1. 
  15.      * */
  16.     publicint _m=6;  
  17.     privateint _min=3;  
  18.     publicint totalKeys=1;  
  19.     /** 
  20.      * 確定該b樹的最大子節點數。 
  21.      * */
  22.     public BtreeGen(int m){  
  23.         _m=m;  
  24.         _min=(int)Math.ceil((double)m/2);  
  25.     }  
  26.     publicboolean insert(float indexNO,Object indexValue){  
  27.         indexUnit iunit=new indexUnit();  
  28.         iunit.indexNo=indexNO;  
  29.         iunit.indexValue=indexValue;  
  30.         TreeUnit needInsertLeaf=recursion_insert_search_leaf_node(indexNO, _btreeRootNode);  
  31.         if(needInsertLeaf==null){  
  32.             //--
  33.             System.out.println("【警告】找不到需要插入的葉節點!");  
  34.             returnfalse;  
  35.         }  
  36.         else{  
  37.             System.out.println("【提示】需要插入的葉節點為:");  
  38.             for(indexUnit iiUnit:needInsertLeaf.keys){  
  39.                 //--
  40.                 System.out.print("  "+iiUnit.indexNo+"  ");  
  41.             }  
  42.         }  
  43.         to_insert(indexNO, indexValue, needInsertLeaf);  
  44.         returntrue;  
  45.     }  
  46. private TreeUnit recursion_insert_search_leaf_node(float indexNO,TreeUnit currentUnit){  
  47. if(currentUnit==null){  
  48.     returnnull;  
  49. }  
  50. //--假如有下屬節點,那麼就必須跳到下一個點。
  51. if(currentUnit.childNodes.size()>0){  
  52.     int childLoc=0;  
  53.     int cindex=0;  
  54.     for(indexUnit iUnit:currentUnit.keys){  
  55.         if(iUnit.indexNo<indexNO){  
  56.             childLoc=cindex+1;  
  57.         }  
  58.         if(iUnit.indexNo==indexNO){  
  59.             //--已經包含該節點了?那麼就返回空,不要再插了。
  60.             returnnull;  
  61.         }  
  62.         cindex++;  
  63.     }  
  64.     TreeUnit childTree=currentUnit.childNodes.get(childLoc);  
  65.     return  recursion_insert_search_leaf_node(indexNO, childTree);  
  66. }  
  67. else{  
  68.     //--沒有下屬節點,那麼就認定是這個葉節點了。
  69.     return currentUnit;  
  70. }  
  71. }  
  72. /* 
  73.  * 主鍵的插入。 
  74.  * */
  75. privatevoid to_insert(float indexNO,Object value,TreeUnit currentUnit){  
  76.     int insertLoc=0;  
  77.     for(indexUnit iUnit:currentUnit.keys){  
  78.         if(iUnit.indexNo>indexNO){  
  79.             break;  
  80.         }  
  81.         insertLoc++;  
  82.     }  
  83.     indexUnit insertedUnit=new indexUnit();  
  84.     insertedUnit.indexNo=indexNO;  
  85.     insertedUnit.indexValue=value;  
  86.     currentUnit.keys.add(insertLoc, insertedUnit);  
  87.     if(currentUnit.keys.size()>_m-1){  
  88.         recursion_division(currentUnit);  
  89.     }  
  90.     else{  
  91.         return;  
  92.     }  
  93. }  
  94. privatevoid recursion_division(TreeUnit currentUnit){  
  95.     if(currentUnit==null){  
  96.         return;  
  97.     }  
  98.    if(currentUnit.keys.size()<=_m-1){  
  99.        return;  
  100.    }  
  101.    if(currentUnit._parent==null){  
  102.        System.out.println("沒有父節點。");  
  103.        TreeUnit leftTree=new TreeUnit();  
  104.        TreeUnit rightTree=new TreeUnit();  
  105.        leftTree._parent=currentUnit;  
  106.        rightTree._parent=currentUnit;  
  107.        indexUnit keyUnit=currentUnit.keys.get(_min-1);  
  108.        int cindex=0;  
  109.        for (indexUnit tmp:currentUnit.keys) {  
  110.            if(cindex<_min-1){  
  111.                leftTree.keys.add(tmp);  
  112.            }  
  113.            elseif(cindex>=_min){  
  114.                rightTree.keys.add(tmp);  
  115.            }  
  116.            cindex++;  
  117.         }  
  118.        int theSize=currentUnit.childNodes.size();  
  119.        currentUnit.keys.clear();  
  120.        currentUnit.keys.add(keyUnit);  
  121.       if(currentUnit.childNodes.size()>0){  
  122.        //--
  123.        for(int ii=0;ii<theSize;ii++){  
  124.            if(ii<=_min-1){  
  125.                currentUnit.childNodes.get(ii)._parent=leftTree;  
  126.                leftTree.childNodes.add(currentUnit.childNodes.get(ii));  
  127.            }  
  128.            else{  
  129.                currentUnit.childNodes.get(ii)._parent=rightTree;  
  130.                rightTree.childNodes.add(currentUnit.childNodes.get(ii));  
  131.            }  
  132.        }  
  133.       }  
  134.        currentUnit.childNodes.clear();  
  135.        currentUnit.childNodes.add(leftTree);  
  136.        currentUnit.childNodes.add(rightTree);  
  137.        return;  
  138.    }  
  139.    System.out.println("父節點不為空。");  
  140.    //--分裂成為了舊節點及新節點兩個節點。
  141.    indexUnit keyUnit=currentUnit.keys.get(_min-1);  
  142.    TreeUnit newTreeUnit=new TreeUnit();  
  143.    newTreeUnit._parent=currentUnit._parent;  
  144.    int cindex=0;  
  145.    for (indexUnit tmp:currentUnit.keys) {  
  146.        if(cindex>=_min){  
  147.            newTreeUnit.keys.add(tmp);  
  148.        }  
  149.        cindex++;  
  150.     }  
  151.    int theSize=currentUnit.keys.size();  
  152.    for(int i2=theSize-1;i2>=_min-1;i2--){  
  153.        currentUnit.keys.remove(i2);  
  154.    }  
  155.    cindex=0;  
  156.    theSize=currentUnit.childNodes.size();  
  157.    for(int ii4=theSize-1;ii4>=_min;ii4--){  
  158.        TreeUnit tmp2=currentUnit.childNodes.get(ii4);  
  159.        tmp2._parent=newTreeUnit;  
  160.        if(newTreeUnit.childNodes.size()<=0){  
  161.            newTreeUnit.childNodes.add(tmp2);  
  162.        }  
  163.        else{  
  164.        newTreeUnit.childNodes.add(0,tmp2);  
  165.        }  
  166.    }  
  167.    for(int ii3=theSize-1;ii3>=_min;ii3--){  
  168.        currentUnit.childNodes.remove(ii3);  
  169.    }  
  170.    int insertPLoc=0;  
  171.    cindex=0;  
  172.    for(indexUnit iUnit:currentUnit._parent.keys){  
  173.        if(iUnit.indexNo<keyUnit.indexNo){  
  174.            insertPLoc=cindex+1;  
  175.        }  
  176.        cindex++;  
  177.    }  
  178.    currentUnit._parent.keys.add(insertPLoc, keyUnit);  
  179.    currentUnit._parent.childNodes.add(insertPLoc+1, newTreeUnit);  
  180.    //--給父節點新增相應子節點。
  181.    if(currentUnit._parent.keys.size()>_m-1){  
  182.        recursion_division(currentUnit._parent);  
  183.    }  
  184.    return;  
  185. }  
  186.     public indexUnit search(float indexNO){  
  187.         _searchResultUnit=null;  
  188.         recursion_search(_btreeRootNode,indexNO);  
  189.         return _searchResultUnit;  
  190.     }  
  191.     private indexUnit _searchResultUnit=null;  
  192.     privatevoid recursion_search(TreeUnit currentUnit, float indexNO){  
  193.      if(currentUnit==null){  
  194.          _searchResultUnit=null;  
  195.          return;  
  196.      }  
  197.      for(indexUnit f1:currentUnit.keys){  
  198.          if(f1.indexNo==indexNO){  
  199.              _searchResultUnit=f1;  
  200.              return;  
  201.          }  
  202.      }  
  203.      //--假如上面都找不到,並且該節點下面沒有子樹了,那麼就表示沒有這個東西。
  204.      if(currentUnit.childNodes.size()<=0){  
  205.          return;  
  206.      }  
  207.      int childTreeIndex=0;  
  208.      int ccIndex=0;  
  209.      for(indexUnit f2:currentUnit.keys){  
  210.          if(f2.indexNo<indexNO){  
  211.              childTreeIndex=ccIndex+1;  
  212.          }  
  213.          ccIndex++;  
  214.      }  
  215.      TreeUnit childTreeUnit=currentUnit.childNodes.get(childTreeIndex);  
  216.      recursion_search(childTreeUnit, indexNO);  
  217.     }  
  218.     private TreeUnit _result_treeUnit=null;  
  219.     /** 
  220.      * 獲取indexNO所在的節點。 
  221.      * */
  222.     public TreeUnit getSearchNode(float indexNO){  
  223.         _result_treeUnit=null;  
  224.         recursion_search_node(_btreeRootNode, indexNO);  
  225.         return _result_treeUnit;  
  226.     }  
  227. /** 
  228.  *搜查indexNO所在的節點。 
  229.  * */
  230.     privatevoid recursion_search_node(TreeUnit treeUnit,float indexNO){  
  231.     if(treeUnit==null){  
  232.         return;  
  233.     }  
  234.     int childChosenIndex=0;  
  235.     int cindex=0;  
  236.     for(indexUnit iTMP:treeUnit.keys){  
  237.         if(indexNO>iTMP.indexNo){  
  238.             childChosenIndex=cindex+1;  
  239.         }  
  240.         if(iTMP.indexNo==indexNO){  
  241.             _result_treeUnit=treeUnit;  
  242.             return;  
  243.         }  
  244.         cindex++;  
  245.     }  
  246.     if(treeUnit.childNodes.size()<=0){  
  247.         return;  
  248.     }  
  249.     //--假如有下面並且當前沒包含相關主鍵,那麼就搜尋下面子節點的。
  250.     TreeUnit childTreeUnit=treeUnit.childNodes.get(childChosenIndex);  
  251.     recursion_search_node(childTreeUnit, indexNO);  
  252.     }  
  253.     publicint[] getRoute(float indexNO){  
  254.                   returnnull;  
  255.     }  
  256.     publicboolean delete(float indexNO){  
  257.         TreeUnit needDelNode=getSearchNode(indexNO);  
  258.         if(needDelNode==null){  
  259.             returnfalse;  
  260.         }  
  261.         return deleteNode(needDelNode, indexNO);  
  262.     }  
  263. /** 
  264.  * 刪除相關節點。 
  265.  * 刪除有幾種情況: 
  266.  * 1、假如是葉節點,並且刪除以後符合b樹的性質,譬如:m=6---最大主鍵數量為5,最少主鍵數量為2,葉節點刪除主鍵後,假如關鍵字數量》=2,那麼就完成刪除操作, 
  267.  * 否則: 
  268.  * 1、看看有沒有左右節點,假如左右節點有空餘的關鍵字,那麼就借用相應的關鍵字, 
  269.  * 假如左右節點的關鍵字數量都是2,沒有空餘的,那麼只能想父節點借用,並且可能會發生合併操作。 
  270.  * 
  271.  * */
  272.     publicboolean deleteNode(TreeUnit needDelNode,float indexNO){  
  273.         //System.out.println("需要刪除的節點為:"+needDelNode.keys.get(0).indexNo);
  274.         //--找到當前關鍵字的在節點裡面的位置。
  275.         int indexLoc=-1;  
  276.         int cindex=0;  
  277.         for(indexUnit iUnit:needDelNode.keys){  
  278.             if(iUnit.indexNo==indexNO){  
  279.                 indexLoc=cindex;  
  280.             }  
  281.             cindex++;  
  282.         }  
  283.         if(indexLoc==-1){  
  284.             returnfalse;  
  285.         }         
  286.         TreeUnit leftChildNode=null;  
  287.         TreeUnit rightChildNode=null;  
  288.         if(needDelNode.childNodes.size()>0){  
  289.             leftChildNode=needDelNode.childNodes.get(indexLoc);  
  290.             rightChildNode=needDelNode.childNodes.get(indexLoc+1);  
  291.         }  
  292.         /** 
  293.          * 假如關鍵字所在節點為根節點,並且沒有任何下屬節點,那麼就直接刪除好了。 
  294.          * */
  295.         if(needDelNode._parent==null&&(needDelNode.childNodes==null||needDelNode.childNodes.size()<=0)){  
  296.             needDelNode.keys.remove(indexLoc);  
  297.             returntrue;  
  298.         }  
  299.         /** 
  300.          * 假如關鍵字包含子節點,那麼就進行相關調整,需要遞迴調整到葉子節點為止。請注意,現在只是調整調換關鍵字的數值,並沒有刪除任何關鍵字,所以 
  301.          * b樹的結構沒有破壞。 
  302.          * */
  303.         /** 
  304.          * a.如果x的左孩子節點存在,x->child[i],並且x->child[i]的節點關鍵字個數至少是n個, 
  305.          * 則找到 child[i]中最大的關鍵字max替換x中刪除的關鍵字,繼續遞迴child[i]刪除關鍵字max。 
  306.          * 這一段話引用自網上,但是我想說,假如該節點不是葉子節點,那麼對於該節點的某一個關鍵字keys[i], 
  307.          * 其左子結點及右子節點child[i]與child[i+1]必然存在----這是b樹的基本性質。 
  308.          * */
  309.         if(needDelNode.childNodes!=null&&needDelNode.childNodes.size()>0){  
  310.             //假如左節點有空餘的關鍵字可以使用(解釋:對於6階b樹--最多6個子樹,每個節點最少有3棵子樹,最多5個節點,最少2個節點,有空餘關鍵字是指關鍵字數量大於或等於3個)
  311.             if(leftChildNode!=null&&leftChildNode.keys.size()>=_min){  
  312.                 int leftLastIndex=leftChildNode.keys.size()-1;  
  313.                 needDelNode.keys.remove(indexLoc);  
  314.                 needDelNode.keys.add(indexLoc,leftChildNode.keys.get(leftLastIndex));  
  315.                 float indexNO1=needDelNode.keys.get(indexLoc).indexNo;  
  316.                 //--遞迴執行
  317.                 return deleteNode(leftChildNode, indexNO1);  
  318.             }  
  319.             //--假如右側節點有關鍵字空餘
  320.             elseif(rightChildNode.keys.size()>=_min){  
  321.                 int rightLastIndex=0;  
  322.                 needDelNode.keys.remove(indexLoc);  
  323.                 needDelNode.keys.add(indexLoc, rightChildNode.keys.get(0));  
  324.                 return deleteNode(rightChildNode, rightChildNode.keys.get(0).indexNo);  
  325.             }  
  326.             else{  
  327.                 //--假如左右子節點都沒有空餘節點了,那麼只能合併了。
  328.                 leftChildNode.keys.add(needDelNode.keys.get(indexLoc));  
  329.                 for(indexUnit iUnit:rightChildNode.keys){  
  330.                     leftChildNode.keys.add(iUnit);  
  331.                 }  
  332.                 for(TreeUnit item1:rightChildNode.childNodes){  
  333.                     leftChildNode.childNodes.add(item1);  
  334.                 }  
  335.                 needDelNode.keys.remove(indexLoc);  
  336.                 needDelNode.childNodes.remove(indexLoc+1);  
  337.                 //--檢查父節點是否符合性質,是否需要回溯合併節點。
  338.                 /** 
  339.                  * 請注意:這個地方是造成回溯合併的主要情形。 
  340.                  * */
  341.                 recursion_checkCombination(needDelNode);  
  342.                 return deleteNode(leftChildNode, indexNO);  
  343.             }  
  344.         }  
  345.         /** 
  346.          *  
  347.          * 假如是葉子節點,那麼就執行相關操作。 
  348.          *  
  349.          * */
  350.         elseif(needDelNode.childNodes==null||needDelNode.childNodes.size()<=0){  
  351.             if(needDelNode.keys.size()>=_min){  
  352.                 needDelNode.keys.remove(indexLoc);  
  353.                 returntrue;  
  354.             }  
  355.             //---
  356.             TreeUnit leftBrother=null;  
  357.             TreeUnit rightBrother=null;  
  358.             TreeUnit parentNode=needDelNode._parent;  
  359.             int childIndexLoc=parentNode.childNodes.indexOf(needDelNode);  
  360.             int keyIndexLoc=-1;  
  361.             if(childIndexLoc==0){  
  362.                 rightBrother=parentNode.childNodes.get(1);  
  363.             }  
  364.             elseif(childIndexLoc==parentNode.childNodes.size()-1){  
  365.                 leftBrother=parentNode.childNodes.get(childIndexLoc-1);  
  366.             }  
  367.             else{  
  368.                 leftBrother=parentNode.childNodes.get(childIndexLoc-1);  
  369.                 rightBrother=parentNode.childNodes.get(childIndexLoc+1);  
  370.             }  
  371.             //--假如左側兄弟存在並且有多餘節點那麼就借用了。
  372.             if(leftBrother!=null&&leftBrother.keys.size()>=_min){  
  373.                 keyIndexLoc=childIndexLoc-1;  
  374.                 needDelNode.keys.add(0,parentNode.keys.get(keyIndexLoc));  
  375.                 parentNode.keys.remove(keyIndexLoc);  
  376.                 parentNode.keys.add(keyIndexLoc,leftBrother.keys.get(leftBrother.keys.size()-1));  
  377.                 leftBrother.keys.remove(leftBrother.keys.size()-1);  
  378.                 return deleteNode(needDelNode, indexNO);  
  379.             }  
  380.             //右側兄弟有多餘的。
  381.             elseif(rightBrother!=null&&rightBrother.keys.size()>=_min){  
  382.                 keyIndexLoc=childIndexLoc;  
  383.                 needDelNode.keys.add(parentNode.keys.get(keyIndexLoc));  
  384.                 parentNode.keys.add(keyIndexLoc,rightBrother.keys.get(0));  
  385.                 parentNode.keys.remove(keyIndexLoc+1);  
  386.                 rightBrother.keys.remove(0);///-------------
  387.                 return deleteNode(needDelNode, indexNO);  
  388.             }  
  389.             //--兩個兄弟都沒有多餘的,那麼就合併好了。
  390.             else{  
  391.                 if(leftBrother!=null){  
  392.                     //leftBrother.keys.add(parentNode.keys.get(keyIndexLoc));
  393.                     keyIndexLoc=childIndexLoc-1;  
  394.                     leftBrother.keys.add(parentNode.keys.get(keyIndexLoc));  
  395.                     for(indexUnit iUnit:needDelNode.keys){  
  396.                         leftBrother.keys.add(iUnit);  
  397.                     }  
  398.                     parentNode.keys.remove(keyIndexLoc);  
  399.                     parentNode.childNodes.remove(keyIndexLoc+1);  
  400.                     recursion_checkCombination(parentNode);  
  401.                     deleteNode(leftBrother, indexNO);  
  402.                     returntrue;  
  403.                 }  
  404.                 elseif(rightBrother!=null){  
  405.                     //needDelNode.keys.remove(indexLoc);
  406.                     keyIndexLoc=childIndexLoc;  
  407.                     needDelNode.keys.add(parentNode.keys.get(keyIndexLoc));  
  408.                     for(indexUnit iUnit:rightBrother.keys){  
  409.                         needDelNode.keys.add(iUnit);  
  410.                     }  
  411.                     parentNode.keys.remove(keyIndexLoc);  
  412.                     parentNode.childNodes.remove(keyIndexLoc+1);  
  413.                     recursion_checkCombination(parentNode);  
  414.                     deleteNode(needDelNode, indexNO);  
  415.                     returntrue;  
  416.                 }  
  417.                 else{  
  418.                     returnfalse;  
  419.                 }  
  420.             }  
  421.         }  
  422.         returntrue;  
  423.     }  
  424.     privatevoid recursion_checkCombination(TreeUnit currentUnit){  
  425.         if(currentUnit==null){  
  426.             return;  
  427.         }  
  428.         if(currentUnit._parent==null&¤tUnit.childNodes.size()<=1){  
  429.             //假如當前節點為根節點,並且沒有關鍵字,那麼根節點丟棄,採用新的根節點。
  430.             _btreeRootNode=currentUnit.childNodes.get(0);  
  431.             _btreeRootNode._parent=null;  
  432.             return;  
  433.         }  
  434.         //假如當前節點為根節點,並且關鍵字為一,那麼就不管了,符合性質。
  435.         if(currentUnit._parent==null){  
  436.             return;  
  437.         }  
  438.         if(currentUnit.keys.size()>=_min-1){  
  439.             return;  
  440.         }  
  441.         //假如不為根節點,並且節點的關鍵字小於_min-1,那麼必須再回溯遞迴合併。
  442.             /** 
  443.              * 分幾種情況,假如左側子節點有空餘關鍵字,那麼從左側節點借,假如右側節點有空餘關鍵字,那麼從右側節點借, 
  444.              * 否則兩邊都沒有隻能繼續遞迴合併了。 
  445.              * */
  446.             TreeUnit parentNode=currentUnit._parent;  
  447.             int indexLOC=currentUnit._parent.childNodes.indexOf(currentUnit);         
  448.             int keyIndexLOC=-1;  
  449.             int childIndexLOC=indexLOC;  
  450.             TreeUnit leftBrother=null;  
  451.             TreeUnit rightBrother=null;  
  452.             if(parentNode.childNodes.size()==2){  
  453.                 if(childIndexLOC==0){  
  454.                     rightBrother=parentNode.childNodes.get(1);  
  455.                 }  
  456.                 else{  
  457.                     leftBrother=parentNode.childNodes.get(0);  
  458.                 }  
  459.             }  
  460.             elseif(parentNode.childNodes.size()>=3){  
  461.                 if(childIndexLOC==0){  
  462.                     rightBrother=parentNode.childNodes.get(1);  
  463.                 }  
  464.                 elseif(childIndexLOC==parentNode.childNodes.size()-1){  
  465.                     leftBrother=parentNode.childNodes.get(childIndexLOC-1);  
  466.                 }  
  467.                 else{  
  468.                     leftBrother=parentNode.childNodes.get(childIndexLOC-1);  
  469.                     rightBrother=parentNode.childNodes.get(childIndexLOC+1);  
  470.                 }  
  471.             }  
  472.             //--左邊兄弟節點有餘錢,那麼就借。
  473.             if(leftBrother!=null&&leftBrother.keys.size()>=_min){  
  474.             keyIndexLOC=childIndexLOC-1;  
  475.             currentUnit.keys.add(0, parentNode.keys.get(keyIndexLOC));  
  476.             currentUnit.childNodes.add(0,leftBrother.childNodes.get(leftBrother.childNodes.size()-1));  
  477.             parentNode.keys.remove(keyIndexLOC);  
  478.             parentNode.keys.add(keyIndexLOC,leftBrother.keys.get(leftBrother.keys.size()-1));  
  479.             leftBrother.keys.remove(leftBrother.keys.size()-1);  
  480.             leftBrother.childNodes.remove(leftBrother.childNodes.size()-1);  
  481.             return;               
  482.             }  
  483.             //--右邊兄弟有餘錢,那麼就借
  484.             elseif(rightBrother!=null&&rightBrother.keys.size()>=_min){  
  485.                 keyIndexLOC=childIndexLOC;  
  486.                 currentUnit.keys.add(parentNode.keys.get(keyIndexLOC));  
  487.                 currentUnit.childNodes.add(rightBrother.childNodes.get(0));  
  488.                 parentNode.keys.remove(keyIndexLOC);  
  489.                 parentNode.keys.add(rightBrother.keys.get(0));  
  490.                 rightBrother.keys.remove(0);  
  491.                 rightBrother.childNodes.remove(0);  
  492.                 return;  
  493.             }  
  494.             //--大家都沒得借,那麼就只能遞迴合併了。
  495.             else{  
  496.                 //--有左側兄弟
  497.                 if(leftBrother!=null){  
  498.                     keyIndexLOC=childIndexLOC-1;  
  499.                     leftBrother.keys.add(parentNode.keys.get(keyIndexLOC));  
  500.                     for(indexUnit iUnit:currentUnit.keys){  
  501.                         leftBrother.keys.add(iUnit);  
  502.                     }  
  503.                     for(TreeUnit tUnit:currentUnit.childNodes){  
  504.                         leftBrother.childNodes.add(tUnit);  
  505.                         tUnit._parent=leftBrother;  
  506.                     }  
  507.                     parentNode.keys.remove(keyIndexLOC);  
  508.                     parentNode.childNodes.remove(keyIndexLOC+1);  
  509.                     recursion_checkCombination(parentNode);  
  510.                     return;  
  511.                 }  
  512.                 else{  
  513.                     //--有右側兄弟
  514.                     keyIndexLOC=childIndexLOC;  
  515.                     currentUnit.keys.add(parentNode.keys.get(keyIndexLOC));  
  516.                     for(indexUnit iUnit:rightBrother.keys){  
  517.                         currentUnit.keys.add(iUnit);  
  518.                     }  
  519.