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