交换二叉树中每个结点的左孩子和右孩子

        在之前的博客中,我们已经掌握了二叉树先序遍历、中序遍历和后序遍历递归算法. 

        本题(只能)选择先序序列(已经过程序验证),并在遍历结点时交换该结点的左右子树顺序即可.

        下面以先序序列作为遍历顺序,进一步设计算法. 

        遍历序列的选择仅仅是"开胃菜",解决本问题的核心是"如何交换某结点的左右子树顺序":大家可以在草稿纸上画出一棵形态具有代表性(即不能过于简单)的二叉树,并交换二叉树中每个结点的左右子树顺序. 相信大家基本上能看出,交换某结点的左右子树顺序,可以转换为如下操作:①如果该结点既有左孩子又有右孩子,那么将该结点的左孩子指针和右孩子指针做一次交换;②如果该结点只有左孩子,那么将右孩子指针指向左孩子,再将左孩子指针置为NULL;③如果该结点只有右孩子,那么将左孩子指针指向右孩子,再将右孩子指针置为NULL;④如果该结点为叶子结点,那么执行空操作. 

        值得一提的是,我一开始只考虑到了上面的①,而没有考虑②和③,这无疑是不严谨的. 大家在思考时,应尽力将情况考虑周到. 根据上面的分析,给出算法的实现代码.

void Swap(BiTreeNode* &T1, BiTreeNode* &T2)//交换两个二叉树结点指针的指向
{
    BiTreeNode* t=T1;
    T1=T2;
    T2=t;
}
void NodeSwap(BiTreeNode* &T)//交换二叉树每个结点的左孩子和右孩子
{
    //此算法根据二叉树先序遍历算法改造而来
    if(T!=NULL)
    {
        if(T->LChild!=NULL&&T->RChild!=NULL)//如果T的左孩子和右孩子都不空
        {
            //将"交换二叉树每个结点的左孩子和右孩子"转换为"交换二叉树每个结点的左孩子的数据域和右孩子的指针域".
            Swap(T->LChild,T->RChild);
        }
        else if(T->LChild!=NULL&&T->RChild==NULL)//如果T的左孩子不空且右孩子为空
        {
            //将T的左子树变为右子树
            T->RChild=T->LChild;
            T->LChild=NULL;
        }
        else if(T->LChild==NULL&&T->RChild!=NULL)//如果T的左孩子为空且右孩子不为空
        {
            //将T的右子树变为左子树
            T->LChild=T->RChild;
            T->RChild=NULL;
        }
        else//如果T的左孩子和右孩子都为空
        {
            //空操作
            ;
        }
        NodeSwap(T->LChild);
        NodeSwap(T->RChild);
    }
    else
    {
        ;
    }
}
原创文章 266 获赞 62 访问量 8万+

猜你喜欢

转载自blog.csdn.net/weixin_42048463/article/details/105888126