题目 :给出一列格式如数据,数据格式如下所示:
{"(1,2)", "(2,4)", "(5,7)", "(7,2)", "(9,5)"}
其中,对于数组内的一个元素,与二叉树的某一节点的对应关系是: 1i是一个二叉树结果的子结果,2i是其父节点
,目前有任务,要求在创建二叉树前或创建过程中对数组做校验,判断数组是否可组成一个合格的二叉树。二叉树的条件是:
- 只能有
1个根节点
; - 一个子节点有且只能有
1
父节点; - 一个父节点
<=2
个子节点;
核心代码(含调试过程中的一些信息):
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class BinaryTreeIncludeSample {
public static void main(String[] args) {
// List listSample = Sample.getSampleList();
// for (Sample sample : listSample) {
System.out.println("");
String result = start(args);
if (result.equals("true")){
System.out.println("true");
}else{
System.out.println("false");
}
//}
}
public static String start(String[] strArr) {
StringBuffer debugInfo = new StringBuffer("");
Map parents = new ConcurrentHashMap<>();
Map childs = new ConcurrentHashMap<>();
if (strArr==null || strArr.length==0){
return "";
}
for(String str:strArr){
String[] ary = str.split(",");
if (ary.length!=2){
return "false";
}
if (ary[0].startsWith("(")){
ary[0] = ary[0].substring(1);
}
if (ary[1].endsWith(")")){
ary[1] = ary[1].substring(0,ary[1].length()-1);
}
int c = Integer.parseInt(ary[0]);
int p = Integer.parseInt(ary[1]);
if (!parents.containsKey(p)){
parents.put (p,new TreeNode(p));
}
if (parents.get(p).left==null){
parents.get(p).left = new TreeNode(c);
}else if (parents.get(p).right==null){
parents.get(p).right = new TreeNode(c);
}else{
// debugInfo.append(p+"有超过2个子节点").toString();
//System.out.println(str.toString());
return "false";
}
if (!childs.containsKey(c)){
childs.put(c,new TreeNode(p,c));
}else if (childs.get(c).left.value != c){
//debugInfo.append(c + "有>1个父节点");
return "false";
}
}
Integer rootIndex = Arrays.asList(parents.keySet().toArray(new Integer[]{})).get(0);
TreeNode rootNode = parents.get(rootIndex);
parents.remove(rootIndex);
childs.remove(rootNode.left.value);
//构建binary tree
AtomicInteger count = new AtomicInteger(parents.size()*4);
createTreeNode(rootNode,rootNode,parents,childs,count);
if (parents.size()>0) {
// List treeNodeList = new CopyOnWriteArrayList<>();
// inorderTraversal(rootNode,treeNodeList);
// List treeValues = treeNodeList.stream().map(item->{return item.value;}).collect(Collectors.toList());
// List list = parents.keySet().stream().map(p->{return "("+parents.get(p).left.value+","+ p +")";}).collect(Collectors.toList());
// debugInfo.append("--BinaryTree:"+treeValues.toString());
// debugInfo.append("--异常多出节点:"+list.toString());
// System.out.println(debugInfo.toString());
return "false";
}else{
return "true";
}
}
public static TreeNode createTreeNode(TreeNode rootNode, TreeNode treeNode, Map parents, Map childs, AtomicInteger count){
if (count.get()==0){
return rootNode;
}
if (rootNode!=null && childs!=null && childs.containsKey(rootNode.value)){
TreeNode node = childs.get(rootNode.value);
node.left = rootNode;
rootNode = node;
parents.remove(node.value);
childs.remove(node.left.value);
count.decrementAndGet();
return createTreeNode(rootNode,treeNode,parents,childs,count);
}
if (treeNode!=null && treeNode.left!=null && parents!=null && parents.containsKey(treeNode.left.value)){
treeNode.left = parents.get(treeNode.left.value);
parents.remove(treeNode.left.value);
count.decrementAndGet();
return createTreeNode(rootNode,treeNode.left,parents,childs,count);
}
if (treeNode!=null && treeNode.right!=null && parents!=null && parents.size()>0 && parents.containsKey(treeNode.right.value)){
treeNode.right = parents.get(treeNode.right.value);
parents.remove(treeNode.right.value);
count.decrementAndGet();
return createTreeNode(rootNode,treeNode.right,parents,childs,count);
}
return rootNode;
}
}
二叉树类
public static class TreeNode{
final private int value;
private TreeNode left;
private TreeNode right;
public TreeNode(int i){
this.value = i;
}
public TreeNode(int i,int leftValue){
this.value = i;
this.left = new TreeNode(leftValue);
}
public String getParentLeft(){
return "("+ left.value +","+ value +")";
}
}
样本数据类
public static class Sample{
String[] strAry;
boolean result;
public Sample(String[] strAry,boolean result){
this.strAry = strAry;
this.result = result;
}
public static List getSampleList(){
List strArrList = new LinkedList(Arrays.asList(new BinaryTree.Sample[]{
new BinaryTree.Sample(new String[]{"(1,2)", "(2,4)", "(5,7)", "(7,2)", "(9,5)"},true),
new BinaryTree.Sample(new String[] {"(1,2)", "(3,2)", "(2,12)", "(5,2)"},false),
new BinaryTree.Sample(new String[]{"(1,2)", "(2,4)", "(5,7)", "(7,2)", "(9,5)"},true),
new BinaryTree.Sample(new String[]{"(1,2)", "(2,4)", "(7,2)"},true),
new BinaryTree.Sample(new String[]{"(1,2)", "(1,2)"},true),
new BinaryTree.Sample(new String[]{},true),
new BinaryTree.Sample(new String[]{"(1,2)", "(1,3)"},false),
new BinaryTree.Sample(new String[]{"(1,2)", "(2,4)", "(7,2)", "(8,8)"},false),
new BinaryTree.Sample(new String[]{"(1,2)", "(4,2)", "(7,2)"},false),
new BinaryTree.Sample(new String[]{"(1,2)", "(4,2)", "(7,9)"},false),
}));
return strArrList;
}
}
附
另外一个样本创建方法
public static TreeNode createTree(int rootIndex, List list) {
if (rootIndex >= list.size()) {
return null;
}
TreeNode rootNode = new TreeNode(list.get(rootIndex));
rootNode.left=createTree( 2 * rootIndex + 1, list);
rootNode.right=createTree(2 * rootIndex + 2, list);
return rootNode;
}
判断二叉树是否相等
public boolean isSamTree(TreeNode m,TreeNode n){
if(m == null && n == null){
return true;
}
if(m == null ^ n == null){
return false;
}
return (m.value == n.value && isSamTree(m.left,n.left) && isSamTree(m.right,n.right));
}
二叉树的遍历(调试时会用上)
/**
* 前序遍历
* @param root
* @param ret
* @return
*/
public static List preorderTraversal(TreeNode root, List ret){
if(root == null) return ret;
if (ret==null){
ret = new LinkedList<>();
}
ret.add(root);
preorderTraversal(root.left,ret);
preorderTraversal(root.right,ret);
return ret;
}
/**
* 中序遍历
* @param root
* @return
*/
public static List inorderTraversal(TreeNode root, List list) {
if(root == null) return null;
if (list==null){
list = new LinkedList<>();
}
inorderTraversal(root.left,list);
list.add(root);
inorderTraversal(root.right,list);
return list;
}
/**
* 后序遍历
* @param root
* @param ret
* @return
*/
public static List postorderTraversal(TreeNode root, List ret) {
if(root == null) return ret;
if (ret==null){
ret = new LinkedList<>();
}
postorderTraversal(root.left,ret);
ret.add(root);
postorderTraversal(root.right,ret);
return ret;
}