B樹的查詢和插入
阿新 • • 發佈:2018-12-09
找了一本書《資料結構教程(Java語言描述),徐孝凱 主編》,寫的挺好的,我發上來大家一起學習。
package p215;
public class BayerTreeNode {
/*根節點非葉節點至少兩個分支,非根非葉至少m/2上整個分支
最多m個分支
每個節點關鍵字的個數是比分支數少一
如非根非葉關鍵字個數(m/2取上整-1)——(m-1)
*/
int m;//B-tree的階,即節點中可容納孩子節點個數(子樹)的最大值
//(m>=3)
int keyNum;//實際儲存了幾個節點
BayerTreeNode parent;//指向父節點的指標域
Object [ ]key=new Object[m+1];//,儲存關鍵字的域
BayerTreeNode[]ptr=new BayerTreeNode[m+1];//指向子樹的指標域
int[]rec=new int[m+1];//儲存關鍵字對應記錄的位置
//key、rec從1開始,ptr從0開始
}
書中為了查詢和插入方便,在每個節點的所有關鍵字後面放上MaxKey,這個最大的鍵不計入keynum
查詢
package p215;
public class BayerTree {
private int m;//m-階B樹
private BayerTreeNode bt;//根
final int MaxKey=1000;//最大鍵值
//注意原來的書裡面新增最後一個位置為最大的MaxKey
//查詢時一定會小於最後的位置,不會超過
public int search(Object k)
{
int i;
BayerTreeNode p=bt;
while(p!=null)
{
i=1;
while(((Comparable)k).compareTo(p.key[i])>0)
i++;
if(k.equals(p.key[i]))
return p.rec[i];
else p=p.ptr[i-1];
}
return -1;
}
插入
public boolean insert(Object k,int num)
{
//向B樹中插入關鍵字為k,記錄儲存位置為num的記錄
//當樹為空
if(bt==null)
{
bt=new BayerTreeNode();
bt.keyNum=1;bt.parent=null;
bt.key[1]=k;bt.key[2]=MaxKey;
bt.rec[1]=num;
bt.ptr[0]=bt.ptr[1]=null;
return true;
}
//從樹上查詢插入位置
int i=0;
BayerTreeNode xp=bt,p=null;//分別指向當前節點和父節點
while(xp!=null)
{
i=1;
while(((Comparable)k).compareTo(xp.key[i])>0)
i++;
if(k.equals(p.key[i]))
return false;
else {
p=xp;
xp=xp.ptr[i-1];
}
}
BayerTreeNode ap=null;
//向非空的B樹中p節點的第i個位置插入索引項(k,num,ap)
while(true)
{
int j,c;
//從最後到插入位置的所有索引項都後移一個位置
for(j=p.keyNum;j>=i;j--)
{
p.key[j+1]=p.key[j];
p.rec[j+1]=p.rec[j];
p.ptr[j+1]=p.ptr[j];
}
//把一個插入索引項(k,num,ap)放入節點p的i位置
p.key[i]=k;p.rec[i]=num;p.ptr[i]=ap;
p.keyNum++;
if(p.keyNum<=m-1)
{
p.key[p.keyNum+1]=MaxKey;
return true;
}
//計算m/2的上整
c=(m%2!=0?(m+1)/2:m/2);
//建立新分裂的結點,該結點含有m-c個索引項
ap=new BayerTreeNode();
ap.keyNum=m-c;ap.parent=p.parent;
for(j=1;j<=ap.keyNum;j++)//複製關鍵字和記錄項
{
ap.key[j]=p.key[j+c];
ap.rec[j]=p.rec[j+c];
}
for(j=0;j<=ap.keyNum;j++)//複製指標
{
ap.ptr[j]=p.ptr[j+c];
if(ap.ptr[j]!=null)
ap.ptr[j].parent=ap;//修改副指標
}
ap.key[m-c+1]=MaxKey;//最大值放入所有關鍵字後
//修改p節點關鍵字個數
p.keyNum=c-1;
//建立新的待向雙親結點插入的索引項(k,num,ap)
k=p.key[c];num=p.rec[c];
//在p結點最後放入最大關鍵字
p.key[c]=MaxKey;
//建立新的樹根結點
if(p.parent==null)
{
bt=new BayerTreeNode();
bt.keyNum=1;bt.parent=null;
bt.key[1]=k;bt.key[2]=MaxKey;
bt.rec[1]=num;
bt.ptr[0]=p;bt.ptr[1]=ap;
p.parent=ap.parent=bt;
return true;
}
//求出新的索引項(k,num,ap)在雙親結點的插入位置
p=p.parent;
i=1;
while(((Comparable)k).compareTo(p.key[i])>0)
i++;
}
}