创建一个二叉树,结点存放的是整型数据,遵循的规则是:第一个数值作为二叉树的树根,小于父节点的值放在左子节点,大于父节点的值放在右子节点。 在创建好二叉树的基础之上,进行结点统计和删除。
统计的内容包括:结点的个数;树的深度;度为0的点的个数;度为1的点的个数;度为2的点的个数。
删除的策略:如果删除结点是叶子结点,直接删除该点;如果删除结点只有一棵子树,子树的根结点直接替代该结点;如果删除结点同时有左子树和右子树,将右子树中的最小值点移动到删除点的位置上来替代删除结点。
输入格式:
输入数值为整型,多行输入。 第一行:二叉树的结点个数N(1≤N≤30)。 第二行:结点的值,以逗号间隔。 第三行:要删除的结点值。
输出格式:
多行输出。第1行输出结点个数。 第2行输出树的深度。 第3行度为0的结点个数。 第4行输出度为1的结点的个数。 第5行输出度为2的结点的个数。第6行为删除前的中序遍历结果。第7行为删除前的广度优先遍历结果 。第8行为删除后的中序遍历结果。第9行为删除后的广度优先遍历结果。具体的格式于要求参见输入输出样例。
输入样例:
在这里给出一组输入。例如:
5
7,2,5,9,12
7
输出样例:
在这里给出相应的输出。例如:
NodeNumbers:5
TreeDepth:3
numbers_0:2
numbers_1:2
numbers_2:1
InOrder:2,5,7,9,12
LayerOrder:7,2,9,5,12
InOrder after:2,5,9,12
LayerOrder after:9,2,12,5
输入样例2:
在这里给出一组输入。例如:
1
3
3
输出样例2:
在这里给出相应的输出。例如:
NodeNumbers:1
TreeDepth:1
numbers_0:1
numbers_1:0
numbers_2:0
InOrder:3
LayerOrder:3
InOrder after:null
LayerOrder after:null
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n=sc.nextInt();
System.out.println("NodeNumbers:"+n);//输出节点数
String s=sc.nextLine();//吞换行符号
String s1=sc.nextLine();
String a[]=s1.split(",");
solution s3=new solution();
s3.storage(a);
System.out.println("TreeDepth:"+s3.deep(s3.root));
System.out.println("numbers_0:"+s3.myzero(s3.root));
System.out.println("numbers_1:"+s3.myone(s3.root));
System.out.println("numbers_2:"+(n-s3.sum-s3.sum1));
System.out.println("InOrder:"+s3.tostringzhongxu(s3.root));
System.out.println("LayerOrder:"+s3.tostringmychengci(s3.root));
int m=sc.nextInt();
TreeNode root=null;
root=s3.root;//此root虽然s3.root内容一样,但地址不同
root=s3.deleteNode(root, m);//传入函数的root也与上面的root内容一样但地址不同
System.out.println("InOrder after:"+s3.tostringzhongxu(root));
System.out.println("LayerOrder after:"+s3.tostringmychengci(root));
}
}
class solution
{
int sum;
int sum1;
static TreeNode t;
static String s="";
static TreeNode root;
//以上变量由于定义在类的内部所以如果调用函数可以直接被内部函数更改内容。
public TreeNode storage(String[] preorder) {//由数组构建搜索二叉树
root=null;//创建头节点
for(String a:preorder)
{
root=add(root,a);
}
return root;//返回头节点
}
private TreeNode add(TreeNode root, String num) {
if(root==null)
return new TreeNode(Integer.valueOf(num));//找到存储位置后直接存储并返回到storage函数,再次寻找下一个元素的储存位置
if(Integer.valueOf(root.val)>Integer.valueOf(num))
{
root.left=add(root.left,num);//根据题意小的存左边,大的存右边
}
else
{
root.right=add(root.right,num);
}
return root;//返回head,继续下次遍历找到新元素的位置
}
public int deep(TreeNode root)
{
return root==null?0:Math.max(deep(root.left),deep(root.right))+1;
}
public String tostringzhongxu(TreeNode root)
{ s="";
myzhongxu(root);
if(s.equals(""))
return null;
return s.substring(0, s.length()-1);
}
private static void myzhongxu(TreeNode root)//中序遍历
{
if(root==null)
return;
myzhongxu(root.left);
s=s+root.val+",";
myzhongxu(root.right);
return;
}
public String tostringmychengci(TreeNode root)//广度优先遍历,(层次遍历)
{
s="";
if(root==null)
return null;
cengci(root);
if(s.equals(""))
return null;
return s.substring(0, s.length()-1);
}
private static void cengci(TreeNode root)//层次遍历二叉树
{
Queue<TreeNode> queue=new LinkedList<TreeNode>();//栈,后进先出
queue.add(root);//存入根节点
while(!queue.isEmpty())
{
TreeNode node =queue.remove();
s=s+node.val+',';//输出根节点
if(node.left!=null)
{
queue.add(node.left);//存入左节点
}
if(node.right!=null)
{
queue.add(node.right);//存入右节点
}
}
return ;
}
public int myzero(TreeNode root)//寻找0节点的函数
{
if(root==null)
return 0;
if(root.left==null&&root.right==null)
sum++;
myzero(root.left);
myzero(root.right);
return sum;
}
public int myone(TreeNode root)//寻找1节点的函数
{
if(root==null)
return 0;
if(root.left==null&&root.right!=null)
sum1++;
if(root.left!=null&&root.right==null)
sum1++;
myone(root.left);
myone(root.right);
return sum1;
}
public TreeNode deleteNode(TreeNode root, int key) {//删除函数
if (root == null) {
return null;
}
if (key < root.val) {
// 待删除节点在左子树中
root.left = deleteNode(root.left, key);
return root;
} else if (key > root.val) {
// 待删除节点在右子树中
root.right = deleteNode(root.right, key);
return root;
} else {
// key == root.val,root 为待删除节点
if (root.left == null) {
// 返回右子树作为新的根
return root.right;
} else if (root.right == null) {
// 返回左子树作为新的根
return root.left;
} else {
// 左右子树都存在,返回后继节点(右子树最左叶子)作为新的根
TreeNode successor = min(root.right);
successor.right = deleteMin(root.right);
successor.left = root.left;
return successor;
}
}
}
private TreeNode min(TreeNode node) {
if (node.left == null) {
return node;
}
return min(node.left);
}
private TreeNode deleteMin(TreeNode node) {
if (node.left == null) {
return node.right;
}
node.left = deleteMin(node.left);
return node;
}
}
class TreeNode {//二叉树储存
int val;
TreeNode left;
TreeNode right;
TreeNode() {}
TreeNode(int val) { this.val = val; }
}