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