剑指offer第二版——面试题26(java)

面试题:树的子结构

题目:输入两颗二叉树A和B,判断B是不是A的子结构。

树结构常用【递归】实现算法

此题需要注意的地方:double类型数的比较

(但是在java中 double_x = double_y表示两个值相同,不代表两个对象是同一个double对象,在这道题里的话,如果前提是double值不为Nan,应该是可以直接比较的意思?

啊 问了下同学 说的是 如果是值是确定的情况下 可以直接比较(?) 但是如果是两个运算 如两个相同的运算如a/b是小数,这个时候不能直接比较,因为是近似值)

代码:

// 2019-06-20
public class Q26 {
	public static void main(String[] args) {
		BinaryTreeNode myTree1 = myTree1();
		BinaryTreeNode myTree2 = myTree2();
		System.out.println(hasEqual(myTree1,myTree2));
	}

    // 递归地比较树的每一个结点,如果根节点等于子树根节点,则进行比较
    public static boolean hasEqual(BinaryTreeNode root1,BinaryTreeNode root2) {
        if(root2==null) {
            return true;
        }
	
        if(root1!=null && root2!=null) {
            boolean flag = false;
		
            flag = flag||isEqual(root1, root2);
            if(flag == false) {
                flag = flag||hasEqual(root1.left, root2)||hasEqual(root1.right, root2);
                return flag;
            }else {
                return true;
            }
        }
        return false;
    }
	
    // 比较当前树
    public static boolean isEqual(BinaryTreeNode root1,BinaryTreeNode root2) {
        if(root1==null && root2==null) {
            return true;
        }
		
        if(root1.val-root2.val<0.00000001 && root2.val-root1.val<0.00000001) {
            return isEqual(root1.left, root2.left) && isEqual(root1.right, root2.right);
        }else {
            return false;
        }
    }
}
// 2019-04-23
public class Q26 {
	public static void main(String[] args) {
		BinaryTreeNode myTree1 = myTree1();
		BinaryTreeNode myTree2 = myTree2();
		System.out.println("tree1:");
		printTree(myTree1);
		System.out.println("\ntree2:");
		printTree(myTree2);
		System.out.println("\n");
		System.out.println(hasEqual(myTree1,myTree2));
	}
	
	// 找到需要比较的位置
		public static boolean hasEqual(BinaryTreeNode tree1,BinaryTreeNode tree2) {
			boolean result = false;
			
			if(tree1!=null && tree2!=null) {
				if(Equal(tree1.val,tree2.val)) {
					result = isSubTree(tree1, tree2);
				}
				if(!result) {
					result = hasEqual(tree1.leftNode, tree2);
				}
				
				if(!result) {
					result = hasEqual(tree1.rightNode, tree2);
				}
			}
			return result;
		}
		
	// 判断是否为子树
	public static boolean isSubTree(BinaryTreeNode tree1,BinaryTreeNode tree2) {
		// 如果比较到tree2已经为null了还没有返回false,则表示之前的都为true
		if(tree2==null) {
			return true;
		}
		// 如果比较到tree1已经为null了,而tree2还有需要比较的结构,说明tree2不为tree1的子结构
		if(tree1==null) {
			return false;
		}
		// 如果当前要比较的结构的根节点都不相等,则表示不为子树
		if(!Equal(tree1.val,tree2.val)) {
			return false;
		}
		//如果根节点相等,则比较左右两支
		boolean flag = isSubTree(tree1.leftNode, tree2.leftNode) && isSubTree(tree1.rightNode, tree2.rightNode);		
		return flag;

	}
	

	public static boolean Equal(double x1,double x2) {
		if(x1-x2<0.0000001 && x2 -x1 < 0.0000001) {
			return true;
		}else {
			return false;
		}
	}
	
	public static BinaryTreeNode myTree1() {
		BinaryTreeNode root = new BinaryTreeNode(8);
		BinaryTreeNode node8 = new BinaryTreeNode(8);
		BinaryTreeNode node7 = new BinaryTreeNode(7);
		root.leftNode = node8;
		root.rightNode = node7;
		BinaryTreeNode node9 = new BinaryTreeNode(9);
		node8.leftNode = node9;
		BinaryTreeNode node2 = new BinaryTreeNode(2);
		node8.rightNode = node2;
		BinaryTreeNode node4 = new BinaryTreeNode(4);
		node2.leftNode = node4;
		BinaryTreeNode node2_7 = new BinaryTreeNode(7);
		node2.rightNode = node2_7;
		return root;
	}
	
	
	public static BinaryTreeNode myTree2() {
		double x1 = 2;
		double x2 = 4;
		double x3 = 7;
		BinaryTreeNode root = new BinaryTreeNode(x1);
		BinaryTreeNode node9 = new BinaryTreeNode(x2);
		root.leftNode = node9;
		BinaryTreeNode node2 = new BinaryTreeNode(x3);
		root.rightNode = node2;
		return root;
	}
	
	// 先序打印
	public static void printTree(BinaryTreeNode root) {
		System.out.printf("%f ", root.val);
		if(root.leftNode!=null) {
			printTree(root.leftNode);
		}
		if(root.rightNode!=null) {
			printTree(root.rightNode);
		}
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值