二叉树的镜像
方法一
递归,交换左孩子和右孩子,然后返回结点地址
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct TreeNode* mirrorTree(struct TreeNode* root){
struct TreeNode *tmp;
//递归结束条件
if(!root){
return NULL;
}
//对左右子树进行递归
root->left = mirrorTree(root->left);
root->right = mirrorTree(root->right);
//交换左右孩子
tmp = root->left;
root->left = root->right;
root->right = tmp;
return root;
}
方法二
辅助栈,只是起到一个保存结点的作用,同样可以通过队列来实现。
队列和栈的作用只是为了保证每个结点都能被访问到一次。同理甚至可以直接用数组将所有结点地址都装入,随后访问每一个结点并交换左右孩子。
借助辅助栈保存结点。并定义一个结点T指针指向被弹出的结点,便于交换左右孩子。
层次遍历,将结点放入栈,随后栈顶出栈,T指向栈顶出栈结点,随后出栈结点的左右孩子入栈,交换T的左右孩子。
最终栈为空结束。
注意:
为了能够访问到出栈元素的左右孩子,压栈压入的是结点的地址,栈中保存的也是结点的地址,出栈时传入的是T的地址。所以出栈结束T指向会发生改变,会指向出栈元素。从而实现在原地址空间修改。
存储n个结点的二叉树最大需要(n+1)/2的空间。最糟糕的时候就是每次出一个入两个。
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* struct TreeNode *left;
* struct TreeNode *right;
* };
*/
struct Stack{
struct TreeNode **stack;
int stacktop;
};
//压栈
int StackPush(struct Stack* S,struct TreeNode* T){
if((S->stacktop == 500) || !T){
return 0;
}
*(S->stack +S->stacktop) = T;
S->stacktop++;
return 1;
}
//弹栈
int StackPop(struct Stack* S,struct TreeNode** T){
if(!S->stacktop || !T){
return 0;
}
S->stacktop--;
*T = *(S->stack +S->stacktop);
return 1;
}
//求二叉树的深度
// int GetDeepth(struct TreeNode* root){
// int L,R;
// if(!root){
// return 0;
// }
// L = GetDeepth(root->left)+1;
// R = GetDeepth(root->right)+1;
// return L>R?L:R;
// }
struct TreeNode* mirrorTree(struct TreeNode* root){
//辅助栈
struct Stack* S = (struct Stack*)malloc(sizeof(struct Stack));
//如果要求空间小,可加一个函数求树的深度,根据深度开辟栈的空间。
S->stack = (struct TreeNode**)malloc(sizeof(struct TreeNode*)*500);
S->stacktop = 0;
struct TreeNode* T = root;
struct TreeNode* tmp;
StackPush(S,T);
while(S->stacktop){
StackPop(S,&T);
if(T->left){
StackPush(S,T->left);
}
if(T->right){
StackPush(S,T->right);
}
tmp = T->left;
T->left = T->right;
T->right = tmp;
}
free(S->stack);
free(S);
return root;
}