二叉排序樹

一、二叉排序樹的定義    二叉排序樹(Binary Sort Tree)又稱二叉查找(搜索)樹(Binary Search Tree)。其定義爲:二叉排序樹或者是空樹,或者是知足以下性質的二叉樹:
 ①若它的左子樹非空,則左子樹上全部結點的值均小於根結點的值;
 ②若它的右子樹非空,則右子樹上全部結點的值均大於根結點的值;
 ③左、右子樹自己又各是一棵二叉排序樹。
   上述性質簡稱二叉排序樹性質(BST性質),故二叉排序樹其實是知足BST性質的二叉樹。   二、二叉排序樹的特色   由BST性質可得:
   (1) 二叉排序樹中任一結點x,其左(右)子樹中任一結點y(若存在)的關鍵字必小(大)於x的關鍵字。
   (2) 二叉排序樹中,各結點關鍵字是唯一的。
   注意:   實際應用中,不能保證被查找的數據集中各元素的關鍵字互不相同,因此可將二叉排序樹定義中BST性質(1)裏的"小於"改成"大於等於",或將BST性質(2)裏的"大於"改成"小於等於",甚至可同時修改這兩個性質。
   (3) 按中序遍歷該樹所獲得的中序序列是一個遞增有序序列。 ①二叉排序樹插入新結點的過程   在二叉排序樹中插入新結點,要保證插入後仍知足BST性質。其插入過程是:
   (a)若二叉排序樹T爲空,則爲待插入的關鍵字key申請一個新結點,並令其爲根;
   (b)若二叉排序樹T不爲空,則將key和根的關鍵字比較:
          (i)若兩者相等,則說明樹中已有此關鍵字key,無須插入。
          (ii)若key<T→key,則將key插入根的左子樹中。
          (iii)若key>T→key,則將它插入根的右子樹中。
   子樹中的插入過程與上述的樹中插入過程相同。如此進行下去,直到將key做爲一個新的葉結點的關鍵字插入到二叉排序樹中,或者直到發現樹中已有此關鍵字爲止。 注意:    輸入序列決定了二叉排序樹的形態。
   二叉排序樹的中序序列是一個有序序列。因此對於一個任意的關鍵字序列構造一棵二叉排序樹,其實質是對此關鍵字序列進行排序,使其變爲有序序列。"排序
樹"的名稱也由此而來。一般將這種排序稱爲樹排序(Tree Sort),能夠證實這種排序的平均執行時間亦爲O(nlgn)。
   對相同的輸入實例,樹排序的執行時間約爲堆排序的2至3倍。所以在通常狀況下,構造二叉排序樹的目的並不是爲了排序,而是用它來加速查找,這是由於在一
個有序的集合上查找一般比在無序集合上查找更快。所以,人們又經常將二叉排序樹稱爲二叉查找樹。


public class BinarySortTree {

	private int data;
	private BinarySortTree lChild;
	private BinarySortTree rChild;
	
	public BinarySortTree(int data){
		this.data = data;
		lChild = null;
		rChild = null;
	}
	
	public BinarySortTree(){
		this.data = 0;
		lChild = null;
		rChild = null;
	}
	
	
	/**
	 * 方法名稱:createTree()
	 * 方法描述:根據數組中的數據信息生成一個二叉查找樹
	 * @param  
	 * @return String    
	 * @Exception 
	 */
	public BinarySortTree createTree(int[] datas){
		BinarySortTree root = new BinarySortTree(datas[0]);
		for(int i=1;i<datas.length;i++){
			insertTree(root, datas[i]);
		}
		return root;
	}


	/**
	 * 方法名稱:insertTree()
	 * 方法描述:向二叉排序樹種插入數據
	 * @param  
	 * @return String    
	 * @Exception 
	 */
	private void insertTree(BinarySortTree root, int data) {
		// TODO Auto-generated method stub
		BinarySortTree child = null;
		if(root != null){
			
			if(data < root.data){
				if(root.lChild == null){
					child = new BinarySortTree(data);
					root.lChild = child;
				}else{
					insertTree(root.lChild, data);
				}
			}else if(data > root.data){
				if(root.rChild == null){
					child = new BinarySortTree(data);
					root.rChild = child;
				}else{
					insertTree(root.rChild, data);
				}
			}else{
				return ;
			}
		}
	}
	
	/**
	 * 方法名稱:inOrder()
	 * 方法描述:中序遍歷
	 * @param  
	 * @return String    
	 * @Exception 
	 */
	public void inOrder(BinarySortTree root){
		if(root != null){
			inOrder(root.lChild);
			System.out.print(root.data + " ");
			inOrder(root.rChild);
		}
	}
	
	/**
	 * 方法名稱:search()
	 * 方法描述:查找元素
	 * @param  
	 * @return String    
	 * @Exception 
	 */
	public boolean search(BinarySortTree root, int data){
		if(root != null){
			if(root.data == data){
				return true;
			}else if(root.data < data){
				return search(root.rChild, data);
			}else {
				return search(root.lChild, data);
			}
		}
		return false;
	}
	
	/**
	 * 方法名稱:delete()
	 * 方法描述:刪除節點
	 * @param 採用遞歸的方式進行刪除  
	 * @return String    
	 * @Exception 
	 */
	public void delete(BinarySortTree root, int data){
		
		if(root != null){
			if(root.data < data){
				//查找右孩子
				delete(root.rChild,data);
			}else if(root.data > data){
				delete(root.lChild,data);
			}else{
				deleteNode(root);
			}
		}
		
	}
	
	/**
	 * 方法名稱:deleteNode()
	 * 方法描述:執行具體的刪除操做
	 * @param  
	 * @return String    
	 * @Exception 
	 */
	private void deleteNode(BinarySortTree p) {
		// TODO Auto-generated method stub
		if(p != null){
			//若是節點有左子樹
			/*1。若p有左子樹,找到其左子樹的最右邊的葉子結點r,用該葉子結點r來替代p,把r的左孩子
			做爲r的父親的右孩子。
			2。若p沒有左子樹,直接用p的右孩子取代它。*/
			if(p.lChild != null){
				BinarySortTree r = p.lChild;
				BinarySortTree prev = p.lChild;
				
				while(r.rChild != null){
					prev = r;
					r = r.rChild;
				}
				p.data = r.data;
				
				//若r不是p的左子樹,p的左子樹不變,r的左子樹做爲r的父節點的右孩子節點
				if(prev != r){
					prev.rChild = r.lChild;
				}else{
					//若r是p的左子樹,則p的左子樹只想r的左子樹
					p.lChild = r.lChild;
				}
			}else{
				p = p.rChild;
			}
		}
	}

	public static void main(String[] args){
		BinarySortTree root = new BinarySortTree();
		int[] datas = {14,9,17,16};//{63,90,70,55,67,42,98,83,10,45,58};
		root = root.createTree(datas);
		root.inOrder(root);
		System.out.println();
		System.out.println(root.search(root, 98));
		root.delete(root, 17);
		root.inOrder(root);
	}
	
}



其中刪除部分思想參考該文:blog.csdn.net/arcsinsin/article/details/10238505 java

文字部分的引用文章爲:http://sjjp.tjuci.edu.cn/sjjg/DataStructure/DS/web/chazhao/chazhao9.1.1.htm web

相關文章
相關標籤/搜索