二叉树翻转是一道比较简单,可是又很是有意思的算法问题,固然了,对于应届生或是正在学习算法的学生来讲,这道题显然是很是简单的,但对于有着多年技术经验的工程师,可能就不必定能写的出来(我指的是白板面试这类在纸类介质上进行书写的状况。)c++
话很少说,咱们直接看题:面试
Invert a binary tree.
4
/ \
2 7
/ \ / \
1 3 6 9
to
4
/ \
7 2
/ \ / \
9 6 3 1复制代码
这个问题的文字描述,简单说来就是将二叉树的左右子树所有翻转过来,使原二叉树的左子树称为新二叉树的右子树。算法
这个问题看起来是否是很简单?但有趣的是,有人是这样评价这个问题:bash
Google: 90% of our engineers use the software you wrote (Homebrew), but you can’t invert a binary tree on a whiteboard so fuck off.学习
产生这种问题的缘由多是多样的,不过不管是什么缘由,对于一个应届生或是正在学习算法的学生来讲,都是必需要忽略的,由于若是不会写算法对应的代码,咱们又如何判断你是真的懂这个算法?总不能让我相信你的一面之词不是?ui
//这是递归方法
TreeNode* invertTree(TreeNode* root) {
if (!root) return nullptr;
else {
TreeNode *temp = root->left;
root->left = root->right;
root->right = temp;
}
invertTree(root->left);
invertTree(root->right);
return root;
}
//进行递归简化
TreeNode* invertTree(TreeNode* root) {
if (root) {
invertTree(root->left);
invertTree(root->right);
std::swap(root->left, root->right);
}
return root;
}
//非递归形式@chammika
TreeNode* invertTree(TreeNode* root) {
std::stack<TreeNode*> stk;
stk.push(root);
while (!stk.empty()) {
TreeNode* p = stk.top();
stk.pop();
if (p) {
stk.push(p->left);
stk.push(p->right);
std::swap(p->left, p->right);
}
}
return root;
}复制代码
这一道题,一眼看过去,咱们马上就能获得的信息是:spa
简化咱们所获得的信息,即获得,咱们须要经过递归来改变双亲的指针以实现翻转操做。设计
其实这道题算的上是一道应用分治思想的典型题了,咱们按照以下步骤进行算法的编写:指针
综上,咱们能够看到,先设计一个递归出口,什么时候可以让递归终止if (!root) return nullptr;
此为出口的一种,咱们也能够将递归出口设置在最后,此时咱们须要设置的是知足什么条件才能开始递归if (root) { /* ... */ }
条件不知足时,咱们能够开始递归的回溯return root
。code
总的来讲,这道题仍是很是简单的(手动滑稽)。