二叉排序树的Java实现

class Node{
	public int data;
	public Node left;
	public Node right;
	public Node(int data){
		this.data = data;
		this.left = null;
		this.right = null;
	}
}
public class BinaryTree {
	
	private Node root;
	public BinaryTree(){//构造函数
		this.root = null;
	}
	//将data插入到排序二叉树中
	public void InsertNode(int data){
		Node newNode = new Node(data);
		if(this.root == null){
			this.root = newNode;
		}else{
			Node current = this.root;
			Node parent = current;
			while(current != null){
				parent = current;
				if(data < current.data){
					current = current.left;
				}else{
					current = current.right;
				}
			}
			if(data < parent.data){
				parent.left = newNode;
			}else{
				parent.right = newNode;
			}
		}
	}
	//构造一颗BST
	public void CreateBST(int[] nums,int n){
		for(int i = 0;i<n;i++){
			InsertNode(nums[i]);
		}
	}
	//查找指定BST的最小关键字
	public Node SearchMin(Node root){
		if(root == null) {
			return null;}
		if(root.left==null){
			return root;
		}else {
			return SearchMin(root.left);
		}		
	} 
	//查找最大关键字
	public Node SearchMax(Node root){
		if(root == null) {
			return null;
		}
		if(root.right==null){
			return root;
		}else {
			return SearchMax(root.right);
		}		
	} 
	//查找值为key的关键字,非递归方法
	public Node SearchBST(Node root,int key){
		while(root != null){
			if(key==root.data){
				return root;
			}else if(key < root.data){
				root = root.left;
			}else{
				root = root.right;
			}
		}
		return null;				
	}
	//查找当前结点的父结点,key为当前结点的值,root为二叉树根结点
	public Node getParent(Node root,int key){
		while(root != null){
			if((root.left != null && key==root.left.data) || (root.right != null && key==root.right.data)){
				return root;
			}else if(key < root.data){
				root = root.left;
			}else{
				root = root.right;		
			}
		}
		return null;				
	} 
	//BST删除值为data的结点
	public void DeleteBST(Node root,int data){
		if(root != null){
			if(root.data == data){//找到该结点
				DelNode(root);
			}else if(root.data > data){
				DeleteBST(root.left,data);
			}else
				DeleteBST(root.right,data);
		}
	}
	/**
	 * 二叉排序树待删除结点p分为三种情况:
	 * 1.p是叶子结点——直接删除
	 * 2.p只有左子树或只有右子树——删除p后,将p的左子树或右子树整个移动到删除结点的位置
	 * 3.p既有左子树也有右子树,找到p中序遍历的直接前驱s(左子树中的最大值),替换p结点,然后再删除结点s
	 */
	public void DelNode(Node p){//要删除的结点为p
		Node temp,s;
		if(p.left==null && p.right==null){//删除元素为叶子结点
			temp = getParent(root,p.data);//temp为结点p的双亲结点
	        if(temp.left == p){
	        	temp.left = null;//如果p为temp的左孩子,则删除p即将temp的左孩子置为null
	        }else{
	        	temp.right = null;
	        }
		}else if(p.left != null && p.right==null){//删除元素有左孩子
			temp = getParent(root,p.data);//temp为结点p的双亲结点
			if(temp.left == p){
	        	temp.left = p.left;
	        }else{
	        	temp.right = p.left;
	        }
		}else if(p.left == null && p.right!=null){//删除元素有右孩子
			temp = getParent(root,p.data);//temp为结点p的双亲结点
			if(temp.left == p){
	        	temp.left = p.right;
	        }else{
	        	temp.right = p.right;
	        }
		}else{//删除元素左右孩子都不为空 ,找到左孩子中最大的,即p的直接前驱s,用s来替换p,然后删除s
	        s = SearchMax(p.left);//p的左子树中最大元素结点s没有右孩子
	        temp = getParent(root,s.data);//找到s的双亲
	        if(temp == p){//p的左子树没有右子树,即s==p.left
	        	p = s;
	        }else{//p的左子树有右结点,s为最右的结点,即s若有子树则只有左子树
	        	p.data = s.data; 
	        	temp.right = s.left;
	        }
	        s = null;   
		}
	}
			
	//二叉树的遍历
	public void PreOrderTraverse(Node root){//先序遍历
		if(root != null){
			System.out.println(root.data);
			PreOrderTraverse(root.left);
			PreOrderTraverse(root.right);
		}
	}
	public void MidOrderTraverse(Node root){//中序遍历
		if(root != null){			
			MidOrderTraverse(root.left);
			System.out.println(root.data+" "+root);
			MidOrderTraverse(root.right);
		}
	}
	public void PostOrderTraverse(Node root){//后序遍历
		if(root != null){			
			PostOrderTraverse(root.left);			
			PostOrderTraverse(root.right);
			System.out.println(root.data);
		}
	}

	public static void main(String[] args) {
		int[] nums= {17,12,19,10,15,18,20,8,11,13,16,14};
		BinaryTree newBST = new BinaryTree();
		
		newBST.CreateBST(nums,nums.length);	
		System.out.println("创建后中序遍历:");
		newBST.MidOrderTraverse(newBST.root);	
				
		newBST.InsertNode(9);
		System.out.println("插入9后中序遍历:");
		newBST.MidOrderTraverse(newBST.root);	
		
		Node Max = newBST.SearchMax(newBST.root);
		System.out.println("二叉树中的max: "+Max.data);
		Node Min = newBST.SearchMin(newBST.root);
		System.out.println("二叉树中的min: "+Min.data);
		
		Node Key = newBST.SearchBST(newBST.root,11);
		System.out.println("查找Key值="+Key.data + ", 则其地址="+Key);
		
		newBST.DeleteBST(newBST.root, 17);
		System.out.println("删除17后中序遍历:");
		newBST.MidOrderTraverse(newBST.root);
		
		System.out.println("*--------------------------------------*");
		
		int[] nums1= {2,4,6,7,98,0,2,6,9,1};
        BinaryTree newBST1 = new BinaryTree();
		
		newBST1.CreateBST(nums1,nums1.length);	
		System.out.println("创建后中序遍历:");
		newBST1.MidOrderTraverse(newBST1.root);	
				
		newBST1.InsertNode(11);
		System.out.println("插入11后中序遍历:");
		newBST1.MidOrderTraverse(newBST1.root);	
		
		Node Max1 = newBST1.SearchMax(newBST1.root);
		System.out.println("二叉树中的max: "+Max1.data);
		Node Min1 = newBST1.SearchMin(newBST1.root);
		System.out.println("二叉树中的min: "+Min1.data);
		
		Node Key1 = newBST1.SearchBST(newBST1.root,11);
		System.out.println("查找Key值="+Key1.data + ", 则其地址="+Key1);
		
		newBST1.DeleteBST(newBST1.root, 6);//重复的两个6,只能删掉后一个6
		System.out.println("删除6后中序遍历:");
		newBST1.MidOrderTraverse(newBST1.root);
	}
}

上述代码执行结果:

创建后中序遍历:
8 bst.Node@15db9742
10 bst.Node@6d06d69c
11 bst.Node@7852e922
12 bst.Node@4e25154f
13 bst.Node@70dea4e
14 bst.Node@5c647e05
15 bst.Node@33909752
16 bst.Node@55f96302
17 bst.Node@3d4eac69
18 bst.Node@42a57993
19 bst.Node@75b84c92
20 bst.Node@6bc7c054
插入9后中序遍历:
8 bst.Node@15db9742
9 bst.Node@232204a1
10 bst.Node@6d06d69c
11 bst.Node@7852e922
12 bst.Node@4e25154f
13 bst.Node@70dea4e
14 bst.Node@5c647e05
15 bst.Node@33909752
16 bst.Node@55f96302
17 bst.Node@3d4eac69
18 bst.Node@42a57993
19 bst.Node@75b84c92
20 bst.Node@6bc7c054
二叉树中的max: 20
二叉树中的min: 8
查找Key值=11, 则其地址=bst.Node@7852e922
删除17后中序遍历:
8 bst.Node@15db9742
9 bst.Node@232204a1
10 bst.Node@6d06d69c
11 bst.Node@7852e922
12 bst.Node@4e25154f
13 bst.Node@70dea4e
14 bst.Node@5c647e05
15 bst.Node@33909752
16 bst.Node@3d4eac69
18 bst.Node@42a57993
19 bst.Node@75b84c92
20 bst.Node@6bc7c054
*--------------------------------------*
创建后中序遍历:
0 bst.Node@4aa298b7
1 bst.Node@7d4991ad
2 bst.Node@28d93b30
2 bst.Node@1b6d3586
4 bst.Node@4554617c
6 bst.Node@74a14482
6 bst.Node@1540e19d
7 bst.Node@677327b6
9 bst.Node@14ae5a5
98 bst.Node@7f31245a
插入11后中序遍历:
0 bst.Node@4aa298b7
1 bst.Node@7d4991ad
2 bst.Node@28d93b30
2 bst.Node@1b6d3586
4 bst.Node@4554617c
6 bst.Node@74a14482
6 bst.Node@1540e19d
7 bst.Node@677327b6
9 bst.Node@14ae5a5
11 bst.Node@6d6f6e28
98 bst.Node@7f31245a
二叉树中的max: 98
二叉树中的min: 0
查找Key值=11, 则其地址=bst.Node@6d6f6e28
删除6后中序遍历:
0 bst.Node@4aa298b7
1 bst.Node@7d4991ad
2 bst.Node@28d93b30
2 bst.Node@1b6d3586
4 bst.Node@4554617c
6 bst.Node@1540e19d
7 bst.Node@677327b6
9 bst.Node@14ae5a5
11 bst.Node@6d6f6e28
98 bst.Node@7f31245a


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值