二叉查找树 BST

BST:

主要的是 search、insert、delete三个操作,理想的效率 都是O (logN)

delete比较复杂,有三种情况:

    1,被删除的结点没有孩子

           直接删除

    2,有一个孩子

           把sub tree 连接到 删除结点的 父节点上

    3,有两个孩子

           思路是:把此问题化为 问题2(只有一个孩子)

           找到删除结点 的 中序前趋结点/中序后继结点,然后用找到的结点替换删除结点。

           然后,删除 找到的前趋/后继 结点(必然只有一个孩子)。

详细的看代码:

Notes:

   用到了 前几天写的 BinaryTree类,算是组合吧

   Console的测试结果:

0 4 7 11 14 19 21 22 29 31 35 39 43 46 48 50 54 59 61 65 69 79 83 86 87 89 91 93 95 97
Test 1:
Got 21
After the delete: 0 4 7 11 14 19 22 29 31 35 39 43 46 48 50 54 59 61 65 69 79 83 86 87 89 91 93 95 97
Test 2:
Ain't got 44

Test 3:
Got 4
After the delete: 0 7 11 14 19 22 29 31 35 39 43 46 48 50 54 59 61 65 69 79 83 86 87 89 91 93 95 97
Test 4:
Ain't got 73

Test 5:
Ain't got 3

/**
 * Build a  BST based on BinaryTree
 * Operations: insert , search, delete
 * @author Jason
 *
 */
public class BinarySearchTree<T extends Comparable<T>> {
	public BinaryTree<T> tree;
	
	public BinarySearchTree()
	{
		tree=new BinaryTree<T>();
	}
	
	public void insert(T item)
	{
		BinaryTree<T> root=tree.findRoot();
		BinaryTree<T> newNode=new BinaryTree<T>(item);
		// empty tree
		if(root.getData()==null)
		{
			root.setData(item);
			return ;
		}
		
		int c;
		boolean flag=true;
		while(flag)
		{
			c=item.compareTo((T)root.getData());
			if(c>0)	// right
			{
				if(root.rightChild==null)
				{
					flag=false;
					root.rightChild=newNode;
					newNode.parent=root;
				}
				else	root=root.rightChild;
			}			
			else if(c<0)	//left
			{
				if(root.leftChild==null)
				{
					flag=false;
					root.leftChild=newNode;
					newNode.parent=root;
				}
				else root=root.leftChild;
			}
			else // got it and ignore
				flag=false;
		}
	}
	
	public BinaryTree<T> search(T key)
	{
		BinaryTree<T> root=tree.findRoot();
		// empty tree
		if(root.getData()==null)
			return null;
		
		int c;
		boolean flag=true;
		while(flag)
		{
			c=key.compareTo((T)root.getData());
			if(c>0)	// right
			{
				if(root.rightChild==null)
					flag=false;
				else	root=root.rightChild;
			}			
			else if(c<0)	//left
			{
				if(root.leftChild==null)
					flag=false;
				else root=root.leftChild;
			}
			else // got it and return it;
				return root;
		}
		return null;
	}
	
	public T delete(T key)
	{
		// not found
		BinaryTree<T> node=search(key);
		if(node==null)	return null;
		
		BinaryTree<T> temp;
		// no child
		if(node.rightChild==null && node.leftChild==null)
		{
			deleteHere(node,null);
			return node.getData();
		}
		
		// two children, replace node with the preceding-inorder-node, then delete p-i-n
		if(node.rightChild!=null && node.leftChild!=null)
		{
			// replace
			temp=findPre(node);
			node.setData( temp.getData() );
			node=temp;
		}
		
		// one child, set temp to be the sub-tree which is needed to attach
		if(node.rightChild!=null)
			temp=node.rightChild;
		else 
			temp=node.leftChild;
		deleteHere(node,temp);
		return node.getData();
	}
	
	// for deleteNode which has one child
	public void deleteHere(BinaryTree<T> node, BinaryTree<T> subTree)
	{
		BinaryTree<T> parent=node.parent;
		if(node==parent.leftChild)
			parent.leftChild=subTree;
		else 
			parent.rightChild=subTree;
	}
	
	// find the preceding-inorder-node
	public BinaryTree<T> findPre(BinaryTree<T> node)
	{
		BinaryTree<T> pre=node.leftChild;
		while(pre.rightChild!=null)
			pre=pre.rightChild;
		return pre;
	}
	
	public static void main(String [] args)
	{
		BinarySearchTree<Integer> bst=new BinarySearchTree<Integer>();
		for(int i=0; i<40 ;i ++)
		{
			int temp=(int)(Math.random()*100);
			bst.insert(temp);
		}
		bst.tree.travellRecursive( bst.tree.findRoot() );
	
		for(int test=1 ; test<=5; test++)
		{
			System.out.println("\nTest "+test+":");
			int temp=(int)(Math.random()*100);
			if(bst.search(temp)!=null)
			{
				System.out.println("Got "+temp);
				bst.delete(temp);
				System.out.print("After the delete: ");
				bst.tree.travellRecursive( bst.tree.findRoot() );
			}
			else 
				System.out.println("Ain't got "+temp);
		}	
	}
}

         

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值