二叉排序树

一、二叉排序树的定义    二叉排序树(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

相关文章
相关标签/搜索