import java.util.*;
class Node
{
int key;
Node left; //该节点的左孩子节点
Node right; //该节点的右孩子节点
Node(int key) //节点的构造方法
{
this.key = key;
left = null;
right = null;
}
}
class Tree //树类
{
void insert(Node root,int k)
{
int value = root.key;
Node node = new Node(k);
if(k < value)
{
if(root.left == null)
{
root.left = node;
}
else
{
insert(root.left,k);
}
}
else if(k > value)
{
if(root.right == null)
{
root.right = node;
}
else
{
insert(root.right,k);
}
}
}
void mid(Node root)
{
if(root == null)
return;
else
{
mid(root.left);
System.out.print(root.key + " ");
mid(root.right);
}
}
void level(Node root)
{
if(root == null)
return;
List<Node> queue = new LinkedList<Node>(); //队列,用LinkedList来模拟
queue.add(root);
while(!(queue.isEmpty()))
{
Node temp = queue.remove(0);
System.out.print(temp.key + " ");
if(temp.left != null)
queue.add(temp.left);
if(temp.right != null)
queue.add(temp.right);
}
System.out.println();
}
void find(Node root,int k)
{
int value = root.key;
if(value == k)
{
System.out.println("Yes!");
}
else if(value != k)
{
if(value > k)
{
if(root.left != null)
find(root.left,k);
else
System.out.println("No!");
}
else if(value < k)
{
if(root.right != null)
find(root.right,k);
else
System.out.println("No!");
}
}
}
void min(Node t) //找这棵树中的最小的节点
{
if(t.left == null)
System.out.println(t.key);
else
{
min(t.left); //递归
}
}
void max(Node t) //找这棵树中的最大节点
{
if(t.right == null)
System.out.println(t.key);
else
{
max(t.right); //递归
}
}
public void delete(Node root,int k)
{
Node current = root;
Node parent = root; //需要建一个父节点
boolean isLeftChild = true; //用来判断是否是左孩子,如果是true,则为左孩子,否则为右孩子,这个左右孩子是相对于要删除节点的左右孩子
while(k != current.key) //找这个要删除的节点,若找到则保存这个要删除节点的父节点,若没找到则输出no this node
{
parent = current;
if(k < current.key)
{
isLeftChild = true;
current = current.left;
}
else
{
isLeftChild = false;
current = current.right;
}
if(current == null)
{
break;
}
}
if(current == null)
System.out.println("No this node!");
else
{
if(current.left == null && current.right == null ) //第一种情况,就是找到的节点是叶子节点
{
if(current == root) //判断找到的叶子节点是不是根节点
root = null;
else //若直接就是叶子节点(非根节点)
{
if(isLeftChild)
{
parent.left = null;
}
else
{
parent.right = null;
}
}
}
if(current.left == null && current.right != null && current != null) //如果找到的节点是左子树空,而右子树不空
{
if(current == root)
{
root = current.right;
}
else
{
if(isLeftChild)
{
parent.left = current.right;
}
else
{
parent.right = current.right;
}
}
}
if(current.right == null && current.left != null && current != null) //如果找到的是右子树为空而左子树不为空
{
if(current == root)
{
root = current.left;
}
else
{
if(isLeftChild)
{
parent.left = current.left;
}
else
{
parent.right = current.left;
}
}
}
if(current.left != null & current.right != null && current != null) //如果找到的是两个子树都存在的节点
{
//@SuppressWarnings("unused")
Node successor = null; //下面这一部分是完成对于外部,也就是原来要删除节点的父节点的建树
successor = getSuccessor(current); //调用getSuccessor方法,得到的这个successor节点就是要删除的节点的中序遍历中的直接的后继节点
if(current == root) //当要删除的节点是根节点,则将后继节点直接作为根节点
{
root = successor;
}
else if(isLeftChild) //若要删除的节点是在其父节点的左子树上,则将后继节点接到父节点的左子树上
{
parent.left = successor;
}
else //若要删除的节点是在其父节点的右子树上,则将后继节点接到父节点的右子树上
{
parent.right = successor;
}
successor.left = current.left; //同时,将原来要删除节点的左子树接到新代替其位置的后继节点的左子树上
}
}
}
public Node getSuccessor(Node delNode) //找到要删除节点的中序遍历的直接后继节点,并且在内部完成对节点的替换。
{
Node successorParent = delNode; //后继节点的父节点
Node successor = delNode; //后继节点
Node current = delNode.right; //当前节点
while(current != null) //若当前节点的右子树不空,则执行以下替换过程;否则直接将当前要删除节点的右子树的节点作为其后继节点
{
successorParent = successor; //用递归来找中序遍历的直接后继节点
successor = current;
current = current.left;
}
if(successor != delNode.right) //这一部分是用来将找到的那个后继节点比较是不是需要删除节点的右节点
{ //注意,这一步只是完成了对新后继节点的右子树的建树
successorParent.left = successor.right; //将后继节点的右子树重新接到找到的后继节点的父节点的左子树上
successor.right = delNode.right; //将当前要删除节点的右子树重新接到找到的后继节点的右子树上
} //完成重新建树
return successor; //最后都返回后继节点
}
}
public class Test
{
public static void main(String args[])
{
@SuppressWarnings("resource")
Scanner scan = new Scanner(System.in);
int n = scan.nextInt();
int array[] = new int[n];
for(int j = 0; j < n; j++)
array[j] = scan.nextInt();
Node root = new Node(array[0]);
Tree tree = new Tree();
for(int i = 0; i < array.length; i++)
{
tree.insert(root, array[i]);
}
int m = scan.nextInt(); //输入一个你要删除的数字
tree.delete(root, m); //执行删除操作
tree.mid(root); //进行中序遍历
System.out.println();
tree.level(root); //进行层次遍历
System.out.print("请输入要查询的数字:"); //进行查询操作
int k = scan.nextInt();
tree.find(root, k);
tree.min(root); //获取树中的最大值
tree.max(root); //获取树中的最小值
}
}
关于java写二叉排序树的问题,实现各种节点的插入,删除,遍历
最新推荐文章于 2022-01-15 09:25:31 发布