剑指Offer面试题18树的子结构(递归),面试题19二叉树的镜像(递归和非递归用栈)

面试题18:树的子结构(递归)

判断二叉树B是不是二叉树A的子树.

思路:两步:1,递归调用hasSubtree先遍历A中有没有结点的值和B的根结点相同,如果有,调用doesTree1HaveTree2做第二步判断。2,判断AB结构是否相同,即递归判断左右结点。

本题Java实现:

public class DoesTree1HaveTree2 {
	private boolean doseTree1HaveTree2(BiTree A,BiTree B){
		if(B == null) return true;//注意if顺序
		if(A == null) return false;
		if(A.value != B.value) return false;
		return doseTree1HaveTree2(A.left, B.left) && doseTree1HaveTree2(A.Right, B.Right);
	}
	private boolean hasSubTree(BiTree A,BiTree B){
		boolean result = false;
		if(A != null && B != null){
			if(A.value == B.value){
				result = doseTree1HaveTree2(A,B);
			}
			if(!result){
				result = hasSubTree(A.left, B);
			}
			if(!result){
				result = hasSubTree(A.Right, B);
			}
		}
		return result;
	}
	public static void main(String[] args){
		DoesTree1HaveTree2 test = new DoesTree1HaveTree2();
		BiTree A1 = new BiTree(0);
		BiTree A2 = new BiTree(1);
		BiTree A3 = new BiTree(2);
		BiTree A4 = new BiTree(3);
		BiTree A5 = new BiTree(4);
		A1.left = A2;
		A1.Right = A3;
		A2.left = A4;
		A2.Right = A5;
		BiTree B1 = new BiTree(1);
		BiTree B2 = new BiTree(3);
		BiTree B3 = new BiTree(4);
		B1.left = B2;
		B1.Right = B3;
		System.out.println(test.hasSubTree(A1, B1));
	}
}
class BiTree{
	int value;
	BiTree left;
	BiTree Right;
	BiTree(int x){
		value = x;
	}
}

面试题19:二叉树的镜像(递归和非递归)

本题递归和非递归的Java实现:

public class MirrorRecursively {
	//递归,先交换结点的左右子结点,然后递归调用左右子结点。
	static void mirrorRecursively(BiTree tree){
		if(tree != null){
			BiTree temp = tree.left;
			tree.left = tree.Right;
			tree.Right = temp;
			if(tree.left != null) mirrorRecursively(tree.left);
			if(tree.Right != null) mirrorRecursively(tree.Right);
		}
	}
	//非递归,用栈。还是先交换左右子结点,然后把根结点压入栈,取左子结点为新的根结点,直到出现左子结点为空,之后根结点出栈,取右子结点为新的根结点,循环。
	static BiTree zhan(BiTree tree){
		BiTree p = tree;
		Stack<BiTree> stack = new Stack<>();
		while(p != null || !stack.isEmpty()){//结点为空,且栈为空时结束
			while(p != null){
				BiTree temp = p.left;
				p.left = p.Right;
				p.Right = temp;
				stack.push(p);
				p=p.left;
			}
			p = stack.pop();
			p = p.Right;
		}
		return tree;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值