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

Posted wxwhnu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指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 ;
View Code

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 ;
View Code

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 
View Code

参考资料

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











以上是关于剑指offer18:操作给定的二叉树,将其变换为源二叉树的镜像。的主要内容,如果未能解决你的问题,请参考以下文章

剑指Offer-Java-二叉树的镜像

剑指offer18

剑指offer 18. 二叉树的镜像

剑指offer(18)二叉树的镜像

剑指offer 18. 面试思路二叉树的镜像

剑指Offer 18. 二叉树的镜像 (二叉树)