Leetcode226. 翻转二叉树(递归、迭代、层序三种解法)
目錄
- 題目
- 1、層序法:
- 2、遞歸法:
- 1、先序遍歷(中左右)
- 2、后序遍歷(左右中)
- 3、遞歸中序遍歷為什么不行(左中右)
- 3、迭代法:
- 1、先序遍歷
- 2、中序遍歷
- 3、后序遍歷
- 為什么迭代法的中序遍歷有效?
題目
翻轉(zhuǎn)一棵二叉樹。
示例:
輸入:
4/
2 7
/ \ /
1 3 6 9
輸出:
4
/
7 2
/ \ /
9 6 3 1
1、層序法:
層序遍歷,然后將同一層的所有結(jié)點(diǎn)的左右孩子交換
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:TreeNode* invertTree(TreeNode* root) {queue<TreeNode*> que;if(root!=NULL) que.push(root);while(!que.empty()){int size = que.size();for(int i =0;i<size;i++){TreeNode* node = que.front();que.pop();TreeNode* tmp;tmp = node->left;node->left = node->right;node->right = tmp;//將左右孩子結(jié)點(diǎn)入隊(duì)列,作為下一層的元素if(node->left) que.push(node->left);if(node->right) que.push(node->right);}}return root;} };2、遞歸法:
遍歷的過程中去翻轉(zhuǎn)每一個結(jié)點(diǎn)的左右孩子就可以達(dá)到整體翻轉(zhuǎn)的效果。
可以使用先序遍歷和后序遍歷,而中序遍歷會把某些結(jié)點(diǎn)的左右孩子翻轉(zhuǎn)兩次。
1、先序遍歷(中左右)
遞歸思考過程:
1、返回值:void 形參:指向結(jié)點(diǎn)的指針
2、終止條件:指向結(jié)點(diǎn)的指針為空指針
3、遞歸內(nèi)部邏輯:先翻轉(zhuǎn)指針指向的結(jié)點(diǎn)的左右孩子,然后遞歸遍歷左右子樹
2、后序遍歷(左右中)
遞歸思考過程:
1、返回值:void 形參:指向結(jié)點(diǎn)的指針
2、終止條件:指向結(jié)點(diǎn)的指針為空指針
3、遞歸內(nèi)部邏輯:先遞歸遍歷左右子樹,再翻轉(zhuǎn)指針指向的結(jié)點(diǎn)的左右孩子
為什么后序遍歷的方法更加快捷?
3、遞歸中序遍歷為什么不行(左中右)
中序遍歷之后是這樣的:
因?yàn)榻粨Q完左右結(jié)點(diǎn)后,想要遍歷右子樹,實(shí)際由于進(jìn)行了交換操作,遍歷的還是原來的左子樹。
如下圖:
3、迭代法:
1、先序遍歷
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:TreeNode* invertTree(TreeNode* root) {stack<TreeNode*> st;if(root !=NULL) st.push(root);while(!st.empty()){TreeNode* node = st.top(); //標(biāo)記操作,直到遇到NULLif(node!=NULL){//將該結(jié)點(diǎn)彈出,避免重復(fù)操作st.pop();//添加右結(jié)點(diǎn)if(node->right) st.push(node->right);//添加左結(jié)點(diǎn)if(node->left) st.push(node->left);//添加中結(jié)點(diǎn)st.push(node);//標(biāo)記st.push(NULL); }//只有遇到空結(jié)點(diǎn)的時候,才將下一個結(jié)點(diǎn)的左右子結(jié)點(diǎn)進(jìn)行交換else{//彈出空結(jié)點(diǎn)st.pop();node = st.top();st.pop(); TreeNode* tmp;tmp = node->left;node->left = node->right;node->right = tmp;}}return root;} };2、中序遍歷
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:TreeNode* invertTree(TreeNode* root) {stack<TreeNode*> st;if(root !=NULL) st.push(root);while(!st.empty()){TreeNode* node = st.top(); //標(biāo)記操作,直到遇到NULLif(node!=NULL){//將該結(jié)點(diǎn)彈出,避免重復(fù)操作st.pop();//添加右結(jié)點(diǎn)if(node->right) st.push(node->right);//添加中結(jié)點(diǎn)st.push(node);//標(biāo)記st.push(NULL); //添加左結(jié)點(diǎn)if(node->left) st.push(node->left);}//只有遇到空結(jié)點(diǎn)的時候,才將下一個結(jié)點(diǎn)的左右子結(jié)點(diǎn)進(jìn)行交換else{//彈出空結(jié)點(diǎn)st.pop();node = st.top();st.pop(); TreeNode* tmp;tmp = node->left;node->left = node->right;node->right = tmp;}}return root;} };3、后序遍歷
/*** Definition for a binary tree node.* struct TreeNode {* int val;* TreeNode *left;* TreeNode *right;* TreeNode(int x) : val(x), left(NULL), right(NULL) {}* };*/ class Solution { public:TreeNode* invertTree(TreeNode* root) {stack<TreeNode*> st;if(root !=NULL) st.push(root);while(!st.empty()){TreeNode* node = st.top(); //標(biāo)記操作,直到遇到NULLif(node!=NULL){//將該結(jié)點(diǎn)彈出,避免重復(fù)操作st.pop();//添加中結(jié)點(diǎn)st.push(node);//標(biāo)記st.push(NULL); //添加右結(jié)點(diǎn)if(node->right) st.push(node->right);//添加左結(jié)點(diǎn)if(node->left) st.push(node->left);}//只有遇到空結(jié)點(diǎn)的時候,才將下一個結(jié)點(diǎn)的左右子結(jié)點(diǎn)進(jìn)行交換else{//彈出空結(jié)點(diǎn)st.pop();node = st.top();st.pop(); TreeNode* tmp;tmp = node->left;node->left = node->right;node->right = tmp;}}return root;} };為什么迭代法的中序遍歷有效?
迭代的中序方法可以,因?yàn)橄葘⒔粨Q前的右子樹值存放到棧內(nèi)了,即使后面進(jìn)行了交換,想要遍歷右子樹時,是取棧內(nèi)交換前的右子樹值,而不是交換后的。
如圖:
總結(jié)
以上是生活随笔為你收集整理的Leetcode226. 翻转二叉树(递归、迭代、层序三种解法)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿拉德之息套装附加多少伤害啊
- 下一篇: 天枢之契约行者剧情介绍