剑指offer18:操作给定的二叉树,将其变换为源二叉树的镜像。

1 题目描述

  操作给定的二叉树,将其变换为源二叉树的镜像。

2 输入描述:

二叉树的镜像定义:源二叉树
    	    8
    	   /      	  6   10
    	 / \  /     	5  7 9 11
    	镜像二叉树
    	    8
    	   /      	  10   6
    	 / \  /     	11 9 7  5

3 思路和方法

  (1)递归思想,先交换根节点的左右子树的位置,然后向下递归,把左右子树的根节点作为下次循环的根节点。

  (2)非递归:所以我们可以采用前序遍历的方法进行操作,每当遇到一个结点的时候,首先判断其是否有左右孩子(有其中之一即可),如果有的话,就交换其左右孩子,然后继续遍历其左右子树,只要不为空就继续交换其左右孩子节点(在交换具有孩子结点的结点的时候,其孩子结点也一并被交换了)。

4. C++核心代码

4.1 循环实现二叉树的镜像,利用栈的“后进先出”特性打印

 1 /*
 2 struct TreeNode {
 3     int val;
 4     struct TreeNode *left;
 5     struct TreeNode *right;
 6     TreeNode(int x) :
 7             val(x), left(NULL), right(NULL) {
 8     }
 9 };*/
10 class Solution {
11 public:
12     void Mirror(TreeNode *root) {
13         if (root == NULL)
14             return;
15
16         stack<TreeNode*> stackTreeNode;
17         stackTreeNode.push(root);
18
19         while (stackTreeNode.size() > 0)
20         {
21             TreeNode *parent = stackTreeNode.top();
22             stackTreeNode.pop();
23
24             TreeNode *Temp = parent->left;
25             parent->left = parent->right;
26             parent->right = Temp;
27
28             if (parent->left)
29                 stackTreeNode.push(parent->left);
30             if (parent->right)
31                 stackTreeNode.push(parent->right);
32         }
33     }
34 };

4.2 递归实现二叉树的镜像,按照先序遍历,如果遇到空的节点或者叶子节点就返回,否则交换两个子树后再改变左右子树  

 1 /*
 2 struct TreeNode {
 3     int val;
 4     struct TreeNode *left;
 5     struct TreeNode *right;
 6     TreeNode(int x) :
 7             val(x), left(NULL), right(NULL) {
 8     }
 9 };*/
10 class Solution {
11 public:
12     void Mirror(TreeNode *pRroot) {
13         if (pRroot == NULL || (pRroot->left == NULL && pRroot->right == NULL))
14             return;
15         TreeNode * tmp = pRroot->left;
16         pRroot->left = pRroot->right;
17         pRroot->right = tmp;
18
19         if (pRroot->left)
20             Mirror(pRroot->left);
21         if (pRroot->right)
22             Mirror(pRroot->right);
23     }
24 };

5. 完整代码

  1 #include<iostream>
  2 #include<stack>
  3 using namespace std;
  4
  5 struct BinaryTreeNode
  6 {
  7     int data;
  8     BinaryTreeNode* leftchild;
  9     BinaryTreeNode* rightchild;
 10
 11     BinaryTreeNode(int t)
 12     {
 13         data = t;
 14         leftchild = NULL;
 15         rightchild = NULL;
 16     }
 17 };
 18
 19
 20 void PreorderTravel(BinaryTreeNode* root)
 21 {
 22     if (root == NULL)
 23     {
 24         return;
 25     }
 26     cout << root->data << "    ";
 27     PreorderTravel(root->leftchild);
 28     PreorderTravel(root->rightchild);
 29 }
 30
 31 //递归实现二叉树的镜像,按照先序遍历,如果遇到空的节点或者叶子节点就返回,否则交换两个子树后再改变左右子树
 32 void MirrorBinaryTree1(BinaryTreeNode* root)
 33 {
 34     if (root == NULL || (root->leftchild == NULL && root->rightchild == NULL))
 35     {
 36         return;
 37     }
 38
 39     BinaryTreeNode * tmp = root->leftchild;
 40     root->leftchild = root->rightchild;
 41     root->rightchild = tmp;
 42
 43     if (root->leftchild)
 44     {
 45         MirrorBinaryTree1(root->leftchild);
 46     }
 47     if (root->rightchild)
 48     {
 49         MirrorBinaryTree1(root->rightchild);
 50     }
 51
 52 }
 53
 54 //循环实现二叉树的镜像,利用栈的“后进先出”特性打印
 55 void MirrorBinaryTree2(BinaryTreeNode* root)
 56 {
 57     if (root == NULL)
 58     {
 59         return;
 60     }
 61
 62     stack<BinaryTreeNode*> stackTreeNode;
 63     stackTreeNode.push(root);
 64
 65     while (stackTreeNode.size() > 0)
 66     {
 67         BinaryTreeNode *parent = stackTreeNode.top();
 68         stackTreeNode.pop();
 69
 70         BinaryTreeNode *Temp = parent->leftchild;
 71         parent->leftchild = parent->rightchild;
 72         parent->rightchild = Temp;
 73
 74         if (parent->leftchild)
 75         {
 76             stackTreeNode.push(parent->leftchild);
 77         }
 78
 79         if (parent->rightchild)
 80         {
 81             stackTreeNode.push(parent->rightchild);
 82         }
 83
 84     }
 85 }
 86
 87
 88 // ====================测试代码====================
 89
 90
 91 // 测试完全二叉树:除了叶子节点,其他节点都有两个子节点
 92 //            8
 93 //      6        10
 94 //   5  7      9  11
 95
 96 BinaryTreeNode* root;
 97 void Test1()
 98 {
 99     root = new BinaryTreeNode(8);
100     root->leftchild = new BinaryTreeNode(6);
101     root->rightchild = new BinaryTreeNode(10);
102     BinaryTreeNode* tmp = root->leftchild;
103     tmp->leftchild = new BinaryTreeNode(5);
104     tmp->rightchild = new BinaryTreeNode(7);
105     tmp = root->rightchild;
106     tmp->leftchild = new BinaryTreeNode(9);
107     tmp->rightchild = new BinaryTreeNode(11);
108
109     cout << "Test1:测试完全二叉树,除了叶子节点,其他节点都有两个子节点" << endl;
110     cout << "原二叉树的先序遍历" << endl;
111     PreorderTravel(root);
112     cout << endl;
113
114     MirrorBinaryTree1(root);
115     cout << "二叉树镜像后的先序遍历" << endl;
116     PreorderTravel(root);
117     cout << endl;
118
119     /*MirrorBinaryTree2(root);
120     cout << "二叉树镜像后的先序遍历" << endl;
121     PreorderTravel(root);
122     cout << endl;*/
123 }
124
125
126 // 测试二叉树:出叶子结点之外,左右的结点都有且只有一个左子结点
127 //            8
128 //          7
129 //        6
130 //      5
131 //    4
132 void Test2()
133 {
134     root = new BinaryTreeNode(8);
135     root->leftchild = new BinaryTreeNode(7);
136     root->rightchild = NULL;
137
138     BinaryTreeNode* tmp = root->leftchild;
139     tmp->leftchild = new BinaryTreeNode(6);
140     tmp->rightchild = NULL;
141
142     tmp = tmp->leftchild;
143     tmp->leftchild = new BinaryTreeNode(5);
144     tmp->rightchild = NULL;
145
146     tmp = tmp->leftchild;
147     tmp->leftchild = new BinaryTreeNode(4);
148     tmp->rightchild = NULL;
149
150     cout << "Test2: 测试二叉树,出叶子结点之外,左右的结点都有且只有一个左子结点" << endl;
151     cout << "原二叉树的先序遍历" << endl;
152     PreorderTravel(root);
153     cout << endl;
154
155     MirrorBinaryTree1(root);
156     cout << "二叉树镜像后的先序遍历" << endl;
157     PreorderTravel(root);
158     cout << endl;
159
160     /*MirrorBinaryTree2(root);
161     cout << "二叉树镜像后的先序遍历" << endl;
162     PreorderTravel(root);
163     cout << endl;*/
164 }
165
166 // 测试二叉树:出叶子结点之外,左右的结点都有且只有一个右子结点
167 //            8
168 //             7
169 //              6
170 //               5
171 //                4
172 void Test3()
173 {
174     root = new BinaryTreeNode(8);
175     root->leftchild = NULL;
176     root->rightchild = new BinaryTreeNode(7);
177
178     BinaryTreeNode* tmp = root->rightchild;
179     tmp->leftchild = NULL;
180     tmp->rightchild = new BinaryTreeNode(6);
181
182     tmp = tmp->rightchild;
183     tmp->leftchild = NULL;
184     tmp->rightchild = new BinaryTreeNode(5);
185
186     tmp = tmp->rightchild;
187     tmp->leftchild = NULL;
188     tmp->rightchild = new BinaryTreeNode(4);
189
190     cout << "Test3:测试二叉树出叶子结点之外,左右的结点都有且只有一个右子结点" << endl;
191     cout << "原二叉树的先序遍历" << endl;
192     PreorderTravel(root);
193     cout << endl;
194
195     MirrorBinaryTree1(root);
196     cout << "二叉树镜像后的先序遍历" << endl;
197     PreorderTravel(root);
198     cout << endl;
199
200     /*MirrorBinaryTree2(root);
201     cout << "二叉树镜像后的先序遍历" << endl;
202     PreorderTravel(root);
203     cout << endl;*/
204 }
205
206 // 测试空二叉树:根结点为空指针
207 void Test4()
208 {
209     root = NULL;
210
211     cout << "Test4:测试空二叉树,根结点为空指针" << endl;
212     cout << "原二叉树的先序遍历" << endl;
213     PreorderTravel(root);
214     cout << endl;
215
216     MirrorBinaryTree1(root);
217     cout << "二叉树镜像后的先序遍历" << endl;
218     PreorderTravel(root);
219     cout << endl;
220
221     /*MirrorBinaryTree2(root);
222     cout << "二叉树镜像后的先序遍历" << endl;
223     PreorderTravel(root);
224     cout << endl;*/
225 }
226
227
228 // 测试只有一个结点的二叉树
229 void Test5()
230 {
231     root = new BinaryTreeNode(8);
232     root->leftchild = NULL;
233     root->rightchild = NULL;
234
235     cout << "Test5:测试只有一个结点8的二叉树" << endl;
236     cout << "原二叉树的先序遍历" << endl;
237     PreorderTravel(root);
238     cout << endl;
239
240     MirrorBinaryTree1(root);
241     cout << "二叉树镜像后的先序遍历" << endl;
242     PreorderTravel(root);
243     cout << endl;
244
245     /*MirrorBinaryTree2(root);
246     cout << "二叉树镜像后的先序遍历" << endl;
247     PreorderTravel(root);
248     cout << endl;*/
249 }
250
251
252 int main()
253 {
254     Test1();
255     Test2();
256     Test3();
257     Test4();
258     Test5();
259
260     system("pause");
261     return 0;
262 }

参考资料

https://blog.csdn.net/yanxiaolx/article/details/52019871



原文地址:https://www.cnblogs.com/wxwhnu/p/11410189.html

时间: 2024-10-14 00:39:27

剑指offer18:操作给定的二叉树,将其变换为源二叉树的镜像。的相关文章

【javascript】操作给定的二叉树,将其变换为源二叉树的镜像。

操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / 6 10 / \ / 5 7 9 11 镜像二叉树 8 / 10 6 / \ / 11 9 7 5 代码如下: function Mirror(root) { // write code here if(root) { var temp = root.left; root.left = root.right; root.right = temp; Mirror(root.left); Mirror(ro

二叉树层次遍历(剑指Offer面试题32:从上到下打印二叉树)

图1所示为二叉树的层次遍历,即按照箭头所指方向,按照1.2.3的层次顺序,对二叉树每个节点进行访问 (此图反映的是自左至右的层次遍历,自右至左的方式类似). 要进行层次遍历,需要建立一个队列.先将二叉树头节点入队列,然后出队列,访问该节点, 如果它有左子树,则将左子树的根结点入队:如果它有右子树,则将右子树的根结点入队.然后出队列,对出队节点访问, 如此反复直到队列为空为止. 1 import java.util.*; 2 class TreeNode 3 { 4 int val; 5 Tree

操作给定的二叉树,将其变换为源二叉树的镜像。

题目描述 输入描述: 二叉树的镜像定义:源二叉树 8 / 6 10 / \ / 5 7 9 11 镜像二叉树 8 / 10 6 / \ / 11 9 7 5 class Solution { public: //栈的非递归 void Mirror(TreeNode *pRoot) { if (pRoot == NULL)return; stack<TreeNode*> st; TreeNode* p = NULL; st.push(pRoot); while (st.size()) { p =

剑指Offer18 顺时针打印矩阵

/************************************************************************* > File Name: 18_PrintMatrixClock.c > Author: Juntaran > Mail: [email protected] > Created Time: 2016年08月30日 星期二 17时32分28秒 **********************************************

操作给定的二叉树,将其变换为源二叉树的镜像

1 class Solution { 2 public: 3 void Mirror(TreeNode *pRoot) { 4 if(pRoot==NULL){ 5 return; 6 } 7 if(pRoot -> left==NULL&&pRoot ->right==NULL){ 8 return; 9 } 10 TreeNode *temp = pRoot -> left; 11 pRoot -> left = pRoot -> right; 12 pR

剑指offer——面试题32:从上到下打印二叉树

void BFS(BinaryTreeNode* pRoot) { if(pRoot==nullptr) { cout<<"empty binary tree!"<<endl; return; } queue<BinaryTreeNode*>pNode; pNode.push(pRoot); while(!pNode.empty()) { BinaryTreeNode* pFront=pNode.front(); pNode.pop(); cout&

剑指offer——二叉树镜像

操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / \ 6 10 / \ / \ 5 7 9 11 镜像二叉树 8 / \ 10 6 / \ / \ 11 9 7 5 代码如下: /** public class TreeNode { int val = 0; TreeNode left = null; TreeNode right = null; public TreeNode(int val) { this.val = val; } } */ imp

【剑指offer】十二,二叉树的镜像

题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 分析:镜像的递归定义就是将原有二叉树中节点的左右子树对调.代码如下: 1 /** 2 public class TreeNode { 3 int val = 0; 4 TreeNode left = null; 5 TreeNode right = null; 6 7 public TreeNode(int val) { 8 this.val = val; 9 10 } 11 12 } 13 */ 14 public class Solut

剑指Offer 二叉树的镜像

题目描述 操作给定的二叉树,将其变换为源二叉树的镜像. 输入描述: 二叉树的镜像定义:源二叉树 8 / 6 10 / \ / 5 7 9 11 镜像二叉树 8 / 10 6 / \ / 11 9 7 5 思路: 直接一个中间指针,递归,交换左右节点,节点为叶子节点的时候返回. AC代码: 1 class Solution { 2 public: 3 void Mirror(TreeNode *pRoot) { 4 if(pRoot==NULL) 5 return ; 6 7 TreeNode *