题目:
请完成一个函数,输入一个二叉树,该函数输出它的镜像。
例如输入:
4
/ \
2 7
/ \ / \
1 3 6 9
镜像输出:
4
/ \
7 2
/ \ / \
9 6 3 1
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/er-cha-shu-de-jing-xiang-lcof
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
#include<iostream>
#include<stack>
#include<queue>
using namespace std;
//在使用typedef时,注意最后一行的双引号是放在最后面的
//刚开始没注意到,一直报错来着~
typedef struct BinaryTree
{
char data;
BinaryTree* pLchild;
BinaryTree* pRchild;
}BINARYTREE, * PBINARYTREE;
PBINARYTREE create_binary_tree(void)
{
//为每个二叉树节点申请内存空间
PBINARYTREE pA = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pB = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pC = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pD = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pE = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pF = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pG = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pH = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pI = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pJ = (PBINARYTREE)malloc(sizeof(BINARYTREE));
PBINARYTREE pK = (PBINARYTREE)malloc(sizeof(BINARYTREE));
//给每个二叉树节点的数据域赋值
pA->data = 'A';
pB->data = 'B';
pC->data = 'C';
pD->data = 'D';
pE->data = 'E';
pF->data = 'F';
pG->data = 'G';
pH->data = 'H';
pI->data = 'I';
pJ->data = 'J';
pK->data = 'K';
//给每个二叉树节点的左右指针域赋值
pA->pLchild = pB;
pA->pRchild = pC;
pB->pLchild = pD;
pB->pRchild = pE;
pC->pLchild = NULL;
pC->pRchild = pF;
pD->pLchild = pG;
pD->pRchild = pH;
pE->pLchild = NULL;
pE->pRchild = pI;
pF->pLchild = pJ;
pF->pRchild = pK;
pG->pLchild = pG->pRchild = NULL;
pH->pLchild = pH->pRchild = NULL;
pI->pLchild = pI->pRchild = NULL;
pJ->pLchild = pJ->pRchild = NULL;
pK->pLchild = pK->pRchild = NULL;
return pA;
}
//对于二叉树的镜像,有三种解法:1、递归。 2、栈模拟二叉树的先序遍历。 3、队列模拟二叉树的层次遍历
//解法一:递归
/* 递归满足三个条件
* 1、递归必须有一个明确的终止条件
* 2、该函数所处理的数据规模必须在递减
* 3、这个转换必须是可解的
*/
//注意 递归写法是无需写while循环的,可是我总是先给他一个循环,注意递归本身就相当于是一种循环了
//在这个代码中主要得就是三行代码 1、swap交换左右子树; 2、递归根节点的左子树; 3、递归根节点的右子树
BinaryTree* mirrorTree1(BinaryTree* root)
{
//不要忘了判断,这个相当于递归终止条件。当传入的根节点为非空才执行下面三行,否则就return nullptr
//所以递归的最后一层就是叶子节点,到达叶子节点时才开始一层一层的返回
if (root == nullptr)
return nullptr;
//主要得三行代码:
swap(root->pLchild, root->pRchild);
mirrorTree1(root->pLchild);
mirrorTree1(root->pRchild);
//因为递归相当于是一层一层压栈,最后再一层一层的出栈,因此return语句也是一层一层返回的时候才会执行。
return root;
}
//解法二:栈模拟
BinaryTree* mirrorTree2(BinaryTree* root)
{
stack<BinaryTree*> s;
if(root)
s.push(root);
while (!s.empty())
{
BinaryTree* node = s.top();
s.pop();
if (node == NULL)
continue;
//注意这里是先交换了左右子树,再把左右子树push进栈中,所以左右子树已经换了
//因为只有这样才能满足取出的时候,按照先序遍历的次序进行展开
swap(node->pLchild, node->pRchild);
s.push(node->pLchild);
s.push(node->pRchild);
}
return root;
}
//解法三:队列模拟
PBINARYTREE mirrorTree3(PBINARYTREE root)
{
queue< PBINARYTREE> q;
if (root)
{
q.push(root);
}
while (q.size())
{
PBINARYTREE tr = q.front();
q.pop();
swap(tr->pLchild, tr->pRchild);
if (tr->pLchild)
q.push(tr->pLchild);
if (tr->pRchild)
q.push(tr->pRchild);
}
return root;
}
int main()
{
PBINARYTREE pT = nullptr;
pT = create_binary_tree();
PBINARYTREE mirror_tree1 = mirrorTree1(pT);
PBINARYTREE mirror_tree2 = mirrorTree2(pT);
PBINARYTREE mirror_tree3 = mirrorTree3(pT);
cout << mirror_tree1->data << endl;
cout << mirror_tree2->data << endl;
cout << mirror_tree3->data << endl;
return 0;
}