二叉树的镜像

二叉树的镜像

在这里插入图片描述

方法一

递归,交换左孩子和右孩子,然后返回结点地址

/**
 * 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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值