1. 程式人生 > >B樹的查詢和插入

B樹的查詢和插入

找了一本書《資料結構教程(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++;
	
		}
		
		
		
		
		
	
		
	}