日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Leetcode226. 翻转二叉树(递归、迭代、层序三种解法)

發(fā)布時間:2023/12/1 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Leetcode226. 翻转二叉树(递归、迭代、层序三种解法) 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

目錄

    • 題目
    • 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)的左右孩子,然后遞歸遍歷左右子樹

/*** 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:void traversal(TreeNode* cur){//終止條件if(cur == NULL) return;//邏輯:先交換左右子樹內(nèi)容,然后對左右子樹依次進(jìn)行遍歷TreeNode* tmp;tmp = cur->left;cur->left = cur->right;cur->right = tmp;traversal(cur->left);traversal(cur->right);}TreeNode* invertTree(TreeNode* root) {traversal(root);return root;} };

2、后序遍歷(左右中)

遞歸思考過程:
1、返回值:void 形參:指向結(jié)點(diǎn)的指針
2、終止條件:指向結(jié)點(diǎn)的指針為空指針
3、遞歸內(nèi)部邏輯:先遞歸遍歷左右子樹,再翻轉(zhuǎn)指針指向的結(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) {}* };*/ /*** 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:void traversal(TreeNode* cur){//終止條件if(cur == NULL) return;traversal(cur->left);traversal(cur->right);TreeNode* tmp;tmp = cur->left;cur->left = cur->right;cur->right = tmp;}TreeNode* invertTree(TreeNode* root) {traversal(root);return root;} };

為什么后序遍歷的方法更加快捷?

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)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。