Java二叉树的镜像带测试用例_树的面试题(一):二叉树的镜像

关于二叉树

二叉树是一种在面试中也会涉及的到数据结构。

一棵二叉树是结点的一个有限集合,该集合或者为空,或者是由一个根结点加上两棵分别称为左子树和右子树的、互不相交的二叉树组成。二叉树的物种不同的形态如下:

7789e54089b17a2de12f2e86ab231bcd.png

二叉树的结构定义有三个部分组成,分别是值域val和指向左右孩子的指针*left和*right。

1 structTreeNode {2 intval;3 struct TreeNode *left;4 struct TreeNode *right;5 TreeNode(intx) :6 val(x), left(NULL), right(NULL) {7 }8 };

面试题:二叉树的镜像

输入二叉树,输出它的镜像。

分析:

树的镜像不是我们所熟知的内容,通常在课本上所熟悉的就是树的遍历等基本的操作。但是我们可以通过图像来把镜像的过程给描述出来。比如像下面的两个二叉树就是互为镜像。

36398b309fe5906fe20f9c616cf34464.png

下面我们来分析,镜像发生的过程是怎么样的。

这两个树根结点都是1,那么先交换根结点的左右结点,得到图2。交换后,我们发现,对于结点2和3来说,它们的子结点的左右顺序没有发生变化。因此还要交换对应的结点。对于根结点的左子树,将其视为一棵新的二叉树,同样的交换其子结点。得到图3。同样的作用于右子树,那么最后的交换就完成了。

dd2eb5837d9816371417714f36be4636.png

总结上面的几个步骤:我们先先序遍历这个树的子结点,如果子结点有子结点,那么就交换,当交换完成所有的非叶子结点,那么就是我们所要求的镜像。

递归方法

从上面的分析可以看出,递归是解决该问题比较明晰的思路,思考起来也比较能够想到。下面是递归的解决方案。

1 void MirrorRecursively(TreeNode *pRoot)2 {3 if((pRoot == NULL) || (pRoot->left == NULL && pRoot->right))4 return;5

6 TreeNode *pTemp = pRoot->left;7 pRoot->left = pRoot->right;8 pRoot->right =pTemp;9

10 if(pRoot->left)11 MirrorRecursively(pRoot->left);12

13 if(pRoot->right)14 MirrorRecursively(pRoot->right);15 }

非递归方法

扩展一下如果,采用循环,如何实现?递归的实现借助于栈,那么循环,利用栈即可。下面给出代码。

void MirrorIteratively(TreeNode*pRoot)

{if(pRoot ==NULL)return;

std::stackstackTreeNode;

stackTreeNode.push(pRoot);while(stackTreeNode.size() > 0)

{

TreeNode*pNode =stackTreeNode.top();

stackTreeNode.pop();

TreeNode*pTemp = pNode->left;

pNode->left = pNode->right;

pNode->right =pTemp;if(pNode->left)

stackTreeNode.push(pNode->left);if(pNode->right)

stackTreeNode.push(pNode->right);

}

}

测试用例

写代码的时候要考虑到各种情况。包括NULL,只有一个结点,普通二叉树,二叉树所有结点只有左结点/右结点等。针对下面几种情况都要满足需求。

66dbc7dd172296296fc420ba1d096a98.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值