java实现二叉搜索树的基本功能

在二叉查找树中:
(01) 若任意节点的左子树不空,则左子树上所有结点的值均小于它的根结点的值;
(02) 任意节点的右子树不空,则右子树上所有结点的值均大于它的根结点的值;
(03) 任意节点的左、右子树也分别为二叉查找树。
(04) 没有键值相等的节点(no duplicate nodes)。

直接上个码:

/**
 * @注:泛型T必须是实现了Comparable接口。
 *
 * @author Linging
 * @date:2019/2/16
 * @param <T> /实现二叉搜索树的基本功能
 */

public class BSTree<T extends Comparable<T>> {
	
	//树根节点
	public BSTNode<T> mRoot;
	
	//树节点类型
	public class BSTNode<T extends Comparable<T>> {
		
		private T key;
		private BSTNode<T> parent;
		private BSTNode<T> left;
		private BSTNode<T> right;
		
		public BSTNode(T key, BSTNode<T> parent, BSTNode<T> left, BSTNode<T> right){
			this.key = key;
			this.parent = parent;
			this.left = left;
			this.right = right;
		}
		
		public T getKey() {
			return key;
		}
		
	}
	
	public BSTree() {
		this.mRoot = null;
	}
	
	public  void insertNode(BSTree<T> bst, BSTNode<T> node) {
		
		BSTNode<T> nodeParent = null;    //要插入节点node的父节点
		BSTNode<T> root = bst.mRoot;	//初始指向根节点
		int cmp;    //判断是左子树还是右子树
		
		//查找插入位置
		while(root != null) {
			nodeParent = root;
			cmp = node.key.compareTo(root.key);
			if(cmp < 0) {
				root = root.left;
			}else {
				root = root.right;
			}
		}
		
		node.parent = nodeParent;
		if(nodeParent == null) {	//没有树根的情况
			bst.mRoot = node;
		}else {
			cmp = node.key.compareTo(nodeParent.key);
			if(cmp < 0) {
				nodeParent.left = node;
			}else {
				nodeParent.right = node;
			}
		}
		
	}
	
	//功能:插入节点
	public void insert(T key) {
		
		//构建节点b
		BSTNode<T> b = new BSTNode<T>(key, null, null, null);
		
		//插入节点b
		if(b != null) {
			insertNode(this,b);
		}
	}
	
	
	//前序遍历
	public void preOrder(BSTNode<T> tree) {
		if(tree !=null) {
			System.out.print(tree.key+" ");
			preOrder(tree.left);
			preOrder(tree.right);
		}
	}
	
	//中序遍历
	public void inOrder(BSTNode<T> tree) {
		if(tree !=null) {
			inOrder(tree.left);
			System.out.print(tree.key+" ");
			inOrder(tree.right);
		}
	}
	
	//后续遍历
	public void postOrder(BSTNode<T> tree) {
		if(tree !=null) {
			postOrder(tree.left);
			postOrder(tree.right);
			System.out.print(tree.key+" ");
		}
	}
	
	//销毁二叉搜索树
	public void dest(BSTNode<T> tree) {
		if(tree == null)
			return;
		if(tree.left != null)
			dest(tree.left);
		if(tree.right != null) 
			dest(tree.right);
		tree = null;
	}
	public void destroy() {
		dest(mRoot);
		mRoot = null;
	}
	
	
	//查找节点为key的节点
	public BSTNode<T> find(BSTNode<T> node, T key) {
		if(node == null) 
			return null;
		
		int cmp = key.compareTo(node.key);
		if(cmp < 0)
			return find(node.left, key);
		else if(cmp > 0)
			return find(node.right, key);
		else
			return node;
	}
	public BSTNode<T> findNode(T key){
		return find(mRoot, key);
	}
	
	//查找树中值最小的节点
	public BSTNode<T> minNode(BSTNode<T> tree){
		if(tree == null)
			return null;
		while(tree.left != null)
			tree = tree.left;
		return tree;
	}
	
	//查找树中值最大的节点
	public BSTNode<T> maxNode(BSTNode<T> tree){
		if(tree == null)
			return null;
		while(tree.right != null)
			tree = tree.right;
		return tree;
	}
	
	//返回x节点的后继节点
	 public BSTNode<T> successor(BSTNode<T> x) {
		 if(x == null)
			 return null;
		     // 如果x存在右孩子,则"x的后继结点"为 "以其右孩子为根的子树的最小结点"。
		 if (x.right != null)
		       return minNode(x.right);
		    // 如果x没有右孩子。则x有以下两种可能:
	        // (01) x是"一个左孩子",则"x的后继结点"为 "它的父结点"。
		    // (02) x是"一个右孩子",则查找"x的最低的父结点,并且该父结点要具有左孩子",找到的这个"最低的父结点"就是"x的后继结点"。
		 BSTNode<T> y = x.parent;
	     while ((y!=null) && (x==y.right)) {
		         x = y;
		         y = y.parent;
		  }
		  return y;
	 }
	 
	 //返回x节点的前驱节点
	 public BSTNode<T> predecessor(BSTNode<T> x) {
		 if(x == null) return null;
		 
		// 如果x存在左孩子,则"x的前驱结点"为 "以其左孩子为根的子树的最大结点"。
		 if(x.left != null)
			 return maxNode(x.left);
		 // 如果x没有左孩子。则x有以下两种可能:
		 // (01) x是"一个右孩子",则"x的前驱结点"为 "它的父结点"。
		 // (01) x是"一个左孩子",则查找"x的最低的父结点,并且该父结点要具有右孩子",找到的这个"最低的父结点"就是"x的前驱结点"。
		 BSTNode<T> y = x.parent;
		 while((y != null) && (x == y.left)) {
			 x = y;
			 y = y.parent;
		 }
		 return y;
	 }
	 
	 //删除树中节点z
	 public boolean remove(BSTree<T> tree, BSTNode<T> node){
		 
		 if(tree == null)
			 return false;
		 
		//处理node节点有左右子树的情况
		 if(node.left != null && node.right != null) {
			 //获取node节点的前驱节点
			 BSTNode<T> predecessor = predecessor(node);
			 
			 //将node节点的值替换为前驱节点的值,实现节点的“移动”
			 node.key = predecessor.key;
			 
			 //把要删除的节点设置为前驱节点,其删除就是下面两种情况了
			 node = predecessor;
		 }
		 
		 //将node只有一个孩子节点和没有孩子节点两种情况一起处理
		//获取要删除节点node的孩子节点,可以是null,
		 BSTNode<T> child;
		 if(node.left != null)
			 child = node.left;
		 else 
			 child = node.right;   
		 
		//将孩子节点和父节点关联上
		 if(child != null)
			 child.parent = node.parent;
		 
		 if(node.parent == null)      //不存在父节点,node为根节点且只有左子树或者右子树
			 mRoot = child;
		 else if(node == node.parent.left) //存在父节点,且node为父节点的左孩子
			 node.parent.left = child;
		 else if(node == node.parent.right)   //存在父节点,且node为父节点的右孩子
			 node.parent.right = child;    
		 
		 	node = null;
			return true; 
	 }
	 
	 public void delete(T key) {
		 BSTNode<T> node = findNode(key);     //查找要删除的节点
		 if(node != null)
			 remove(this, node);
	 }
	 
	//打印二叉搜索树
		public void print(BSTNode<T> tree, int height) {
			if(tree != null) {
				for(int i = 1; i <= height; i++)
					System.out.print("-");
				System.out.print(tree.key+"\n");
				print(tree.left, height+1);
				print(tree.right, height+1);	
			}
		}
	
	
	public static void main(String[] args) {
		
		BSTree<Integer> bst = new BSTree<Integer>(); 
		
		//依次插入节点2,4,5,1,3
		bst.insert(2);
		bst.insert(4);
		bst.insert(5);
		bst.insert(1);
		bst.insert(3);
		
		//打印二叉搜索树
		bst.print(bst.mRoot, 1);
		System.out.println();
		
		//前序遍历
		bst.preOrder(bst.mRoot);		//2,1,4,3,5
		System.out.println();
		
		//中序遍历
		bst.inOrder(bst.mRoot);			//1,2,3,4,5
		System.out.println();
		
		//后续遍历
		bst.postOrder(bst.mRoot);		//1,3,5,4,2
		System.out.println();
		
		//查找节点9
		System.out.println(bst.findNode(9));   // null
		
		//返回节点1的后继节点
		System.out.println(bst.successor(bst.findNode(1)).key);   // 2
		
		//返回节点5的前驱节点
		System.out.println(bst.predecessor(bst.findNode(5)).key);   //4
		
		//树中值最小的节点
		System.out.println(bst.minNode(bst.mRoot).key);    // 1
		
		//树中值最大的节点
		System.out.println(bst.maxNode(bst.mRoot).key);    // 5
		
		//删除节点2
		bst.delete(2);
		
		bst.preOrder(bst.mRoot);	//1,4,3,5
		System.out.println();
		
		bst.inOrder(bst.mRoot);		//1,3,4,5
		System.out.println();
		
		bst.postOrder(bst.mRoot);	//3,5,4,1
		System.out.println();
		
		//打印二叉搜索树
		bst.print(bst.mRoot, 1);
		System.out.println();
		
		//销毁二叉搜索树
		bst.destroy();
	}
	
}

学习自:http://www.cnblogs.com/skywang12345/p/3576452.html
https://blog.youkuaiyun.com/isea533/article/details/80345507

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值