二叉樹翻轉是一道比較簡單,可是又很是有意思的算法問題,固然了,對於應屆生或是正在學習算法的學生來講,這道題顯然是很是簡單的,但對於有着多年技術經驗的工程師,可能就不必定能寫的出來(我指的是白板面試這類在紙類介質上進行書寫的狀況。)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
總的來講,這道題仍是很是簡單的(手動滑稽)。