java二叉查找树

/**
 * 二叉查找树的节点不同:
 * 含有一个key值,一个左右节点以及父节点。
 **/
package DataStructure;

/**
 * Copyright 2014 by Ruiqin Sun
 * All right reserved
 * created  on 2014-9-9 下午5:05:13
 **/

	public class SearchTreeNode{
		private int key;
		private SearchTreeNode leftNode;
		private SearchTreeNode rightNode;
		private SearchTreeNode parent;
		
		public SearchTreeNode(int key, SearchTreeNode leftNode, SearchTreeNode rightNode, SearchTreeNode parentNode){
			this.key = key;
			this.leftNode = leftNode;
			this.rightNode = rightNode;
			this.parent = parentNode;
		}
		/**
		 * @return the key
		 */
		public int getKey() {
			return key;
		}
		/**
		 * @param key the key to set
		 */
		public void setKey(int key) {
			this.key = key;
		}
		/**
		 * @return the leftNode
		 */
		public SearchTreeNode getLeftNode() {
			return leftNode;
		}
		/**
		 * @param leftNode the leftNode to set
		 */
		public void setLeftNode(SearchTreeNode leftNode) {
			this.leftNode = leftNode;
		}
		/**
		 * @return the rightNode
		 */
		public SearchTreeNode getRightNode() {
			return rightNode;
		}
		/**
		 * @param rightNode the rightNode to set
		 */
		public void setRightNode(SearchTreeNode rightNode) {
			this.rightNode = rightNode;
		}
		/**
		 * @return the parent
		 */
		public SearchTreeNode getParent() {
			return parent;
		}
		/**
		 * @param parent the parent to set
		 */
		public void setParent(SearchTreeNode parent) {
			this.parent = parent;
		}
	
	}


/**
 * 二叉查找树
 * 方便进行插入删除以及查找
 **/
package DataStructure;

import java.util.ArrayList;
import java.util.List;

/**
 * Copyright 2014 by Ruiqin Sun
 * All right reserved
 * created  on 2014-9-9 下午8:18:07
 **/
public class BinSearchTree {
	private SearchTreeNode root = null;
	// 遍历结点列表  
    private List<SearchTreeNode> nodelist = new ArrayList<SearchTreeNode>();
	public boolean isEmpty(){
		if(root == null){
			return true;
		}else{
			return false;
		}
	}
	
	/**
	 * 依据给定的关键字查找二叉树
	 * @param int key 给定关键字
	 * @return SearchTreeNode 匹配给定关键字的树结点 
	 */
	public SearchTreeNode search(int key){
		SearchTreeNode pNode = root;
		while(pNode != null && pNode.getKey() != key){
			if(key < pNode.getKey()){
				pNode = pNode.getLeftNode();
			}else{
				pNode = pNode.getRightNode();
			}
		}//end while 
		return pNode;
	}

	/**
	 * 将给定的关键字插入到查找二叉树
	 * @param int key 给定关键字
	 * @return 
	 */
	public void  insert(int key){
		SearchTreeNode parentNode = null;
//		首先必须县创建一个关键字为key的SearchTreeNode
		SearchTreeNode newNode = new SearchTreeNode(key, null, null ,null);
		SearchTreeNode pNode = root;
		if(this.isEmpty()){
			root = newNode;
			return;
		}else{
			while(pNode != null){// 从根节点开始循环,将key放到合适的地方
				parentNode = pNode;//首先将pNode值保持
				if(key < pNode.getKey()){
					pNode = pNode.getLeftNode();
				}else if (key > pNode.getKey()){
					pNode = pNode.getRightNode();
				}else{
					//当key值已存在时,直接返回
					return; 
				}
			}//end while
//			System.out.println(parentNode.getKey());
			if(key < parentNode.getKey()){//插入左树
				parentNode.setLeftNode(newNode);
				newNode.setParent(parentNode);
			}else{
				parentNode.setRightNode(newNode);
				newNode.setParent(parentNode);
			}
		}
		 
	}
	
	/** 
	 *minElemNode: 在查询二叉树中查找关键字最小的树节点(左子树的最末尾的节点)
	 * @return 关键字最小的树节点 
	 * throws Exception
	 */
	
	public SearchTreeNode minElemNode(SearchTreeNode node ) throws Exception{
		if(node == null){
			throw new Exception("树为空!");
		}
		while(node.getLeftNode() != null){
			node = node.getLeftNode();
		}
		return node;
	}
	/** 
	 *maxElemNode: 在查询二叉树中查找关键字最大的树节点(右子树的最末尾的节点)
	 * @return 关键字最大的树节点 
	 * throws Exception
	 */
	
	public SearchTreeNode maxElemNode(SearchTreeNode node ) throws Exception{
		if(node == null){
			throw new Exception("树为空!");
		}
		while(node.getRightNode() != null){
			node = node.getRightNode();
		}
		return node;
	}	
	
	/**获取给定结点在中序遍历顺序下的后继结点 
	 * @param SearchTreeNode node 给定树节点
	 * @return SearchTreeNode successor  若该结点存在中序遍历顺序下的后继结点,则返回其后继结点;否则返回 null 
	 * throws Exception
	 */
	public  SearchTreeNode successor(SearchTreeNode pNode) throws Exception{
		if(pNode == null){
			return null;
		}
//		在查询二叉树中查找PNode右子树中关键字就小的树节点
		while(pNode.getRightNode() != null){
			return minElemNode(pNode.getRightNode());
		}
//		若右子树为空,则pNode的后继节点是pnode的parent的parent(按照左-中-右的遍历顺序而得)
		SearchTreeNode parent = pNode.getParent();
		if(parent != null && pNode == parent.getRightNode()){
			pNode = parent;
			parent = parent.getParent();
		}
		return parent;
	}
	
	/**获取给定结点在中序遍历顺序下的前继结点 
	 * @param SearchTreeNode node 给定树节点
	 * @return SearchTreeNode successor  若该结点存在中序遍历顺序下的后继结点,则返回其前继结点;否则返回 null 
	 * throws Exception
	 */
	public  SearchTreeNode preccessor(SearchTreeNode pNode) throws Exception{
		if(pNode == null){
			return null;
		}
//		在查询二叉树中查找PNode左子树中关键字就大的树节点
		while(pNode.getLeftNode() != null){
			return maxElemNode(pNode.getLeftNode());
		}
//		若左子树为空,则pNode的后继节点是pnode的parent的parent(按照左-中-右的遍历顺序而得)
		SearchTreeNode parent = pNode.getParent();
		if(parent != null && pNode == parent.getRightNode()){
			pNode = parent;
			parent = parent.getParent();
		}
		return parent;
	}
	/**
	 * 将给定的关键字从查找二叉树中删除
	 * @param int key 给定关键字
	 * 首先找到关键字为key的树节点pNode,然后判断:
	 * 如果pNode左子节点为空,右子节点不为空则,将右子节点与pNode的父节点相连
	 * 如果pNode左子节点不为空,右子节点为空则,将左子节点与pNode的父节点相连
	 * 如果pNode左子节点不为空,右子节点也不为空则,将PNode的后继结点删除,然后用后继结点代替此节点(后继结点的值赋给此节点即可)
	 * @return  
	 */
	
	public void  delete(int key) throws Exception{
//		首先找到一个关键字为key的SearchTreeNode
		SearchTreeNode pNode =search(key);
		if(pNode == null){
			throw new Exception("树中不存在要删除的关键字!");  
		}
		delete(pNode);
	}
	
	/**
	 * 将给定的关键字从查找二叉树中删除
	 * @param SearchTreeNode nodey 给定树节点
	 * 如果pNode左子节点为空,右子节点不为空则,将右子节点与pNode的父节点相连
	 * 如果pNode左子节点不为空,右子节点为空则,将左子节点与pNode的父节点相连
	 * 如果pNode左子节点不为空,右子节点也不为空则,将PNode的后继结点删除,然后用后继结点代替此节点(后继结点的值赋给此节点即可)
	 * @return  
	 */
	
	public void  delete(SearchTreeNode node) throws Exception{
//		如果node为空直接返回
		if(node == null){
			return;
		}
//		当左子节点为空,右子节点空,直接删除,判断node是parent的左/右位置,将对应的位置设为null
		if(node.getLeftNode() == null && node.getRightNode() == null){
			SearchTreeNode parent = node.getParent();
			if(node == parent.getLeftNode()){
				parent.setLeftNode(null);
			}else{
				parent.setRightNode(null);
			}
			return; //必须跳出此函数,结束删除
		} 
		
//		当左子节点为非空,右子节点空,直接删除,判断node是parent的左/右位置,将左子节点代替node(需要双向设置)
		if(node.getLeftNode() != null && node.getRightNode() == null){
			SearchTreeNode parent = node.getParent();
			if(node == parent.getLeftNode()){
				parent.setLeftNode(node.getLeftNode());
				node.getLeftNode().setParent(parent) ;
			}else{
				parent.setRightNode(node.getLeftNode());
				node.getLeftNode().setParent(parent) ;
			}
			return; //必须跳出此函数,结束删除
		} 
		
//		当左子节点为空,右子节点非空,直接删除,判断node是parent的左/右位置,将右子节点代替node(需要双向设置)
		if(node.getLeftNode() == null && node.getRightNode() != null){
			SearchTreeNode parent = node.getParent();
			if(node == parent.getLeftNode()){
				parent.setLeftNode(node.getRightNode());
				node.getRightNode().setParent(parent) ;
			}else{
				parent.setRightNode(node.getRightNode());
				node.getRightNode().setParent(parent) ;
//				delete(node.getRightNode());
//				node.setKey(node.getRightNode().getKey());
			}
			return; //必须跳出此函数,结束删除
		} 
//		当左子节点、右子节点都非空,则删除该结点的后继结点,并用该后继结点取代该结点
		if(node.getLeftNode() != null && node.getRightNode() != null){
			SearchTreeNode successor =successor(node);
			delete(successor);
			node.setKey(successor.getKey());
		} 
	}
	
	/*
	 *前序遍历二叉树
	 * */
	public void preOrder(SearchTreeNode node){
		if(node != null){
			System.out.print(node.getKey());
			preOrder(node.getLeftNode());
			preOrder(node.getRightNode());
		}
	}
	/*
	 *中序遍历二叉树
	 * */
	public void inOrder(SearchTreeNode node){
		if(node != null){
			inOrder(node.getLeftNode());
			System.out.print(node.getKey());
			inOrder(node.getRightNode());
		}
	}
	/*
	 *后序遍历二叉树
	 * */
	public void postOrder(SearchTreeNode node){
		if(node != null){
			postOrder(node.getLeftNode());			
			postOrder(node.getRightNode());	
			System.out.print(node.getKey());
		}
	}
	
	/**中序遍历二叉树 获得树节点的列表
	 * @params
	 * @return
	 */
	private List<SearchTreeNode> inOderList() {
		// TODO Auto-generated method stub
		if(nodelist !=null){//首先清空节点雷彪,重新获取
			nodelist.clear();
		}
		inOderList(root);
		return nodelist;
	}

	  /** 
     * inOrderTraverse: 对给定二叉查找树进行中序遍历 
     
     *  
     * @param root 
     *            给定二叉查找树的根结点 
     */ 
	private void inOderList(SearchTreeNode root) {
		// TODO Auto-generated method stub
		if(root != null){
			 inOderList(root.getLeftNode());
			 nodelist.add(root);
			 inOderList(root.getRightNode());
		}
	}

	/** 
     * toStringOfOrderList: 获取二叉查找树中关键字的有序列表 
     *  
     * @return 二叉查找树中关键字的有序列表 
     */  
    public String toStringOfOrderList() { 
    	StringBuilder sbuilder = new StringBuilder("[");
    	for(SearchTreeNode node : inOderList()){
    		sbuilder.append(node.getKey());
    		sbuilder.append(" ");
    	}
    	sbuilder.append("]");  
//    	System.out.println(sbuilder.toString());
        return sbuilder.toString();
    	
    }
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
      try{
    	  BinSearchTree bst = new BinSearchTree();
    	  System.out.println("查找树是否为空? " + (bst.isEmpty() ? "是" : "否"));
    	  int[] keys = new int[] { 15, 6, 18, 3, 7, 13, 20, 2, 9, 4 };
    	  for(int key :keys ){
    		  System.out.println("insert " +key); 
    		  bst.insert(key);
    		 
    	  }
    	  System.out.println("中序遍历: " );
    	  bst.inOrder(bst.root);
    	  System.out.println(" " );
    	  System.out.println("转化为String: "+bst.toStringOfOrderList() );
    	  SearchTreeNode maxKeyNode = bst.maxElemNode(bst.root);  
          System.out.println("最大关键字: " + maxKeyNode.getKey());
//          System.out.println("删除key=18的树节点(只有右子树):" );
//          bst.delete(18);
//          System.out.println("删除key=18的树节点后的bst转化为String: "+bst.toStringOfOrderList() );
//          System.out.println("删除key=13的树节点(只有左子树) :" );
//          bst.delete(13);
//          System.out.println("删除key=13的树节点后的bst转化为String: "+bst.toStringOfOrderList() );
          System.out.println("删除key=3的树节点(有左子树和右子树) :" );
          bst.delete(3);
          System.out.println("删除key=3的树节点后的bst转化为String: "+bst.toStringOfOrderList() );
          System.out.println("中序遍历: " );
    	  bst.inOrder(bst.root);
      }catch(Exception e){
    	  System.out.println(e.getMessage());
    	  e.printStackTrace();
      }
	}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值