求二元查找树的镜像

简介: 题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。 例如输入:      8    /  \  6      10 /\       /\5  7    9   11 输出:       8 ...

 

题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。

例如输入:

     8
    /  \
  6      10
 /\       /\
5  7    9   11

输出:

      8
    /  \
  10    6
 /\      /\
11  9  7  5

定义二元查找树的结点为:

struct BSTreeNode // a node in the binary search tree (BST)
{
      int          m_nValue; // value of node
      BSTreeNode  *m_pLeft;  // left child of node
      BSTreeNode  *m_pRight; // right child of node
};

分析:尽管我们可能一下子不能理解镜像是什么意思,但上面的例子给我们的直观感觉,就是交换结点的左右子树。我们试着在遍历例子中的二元查找树的同时来交换每个结点的左右子树。遍历时首先访问头结点8,我们交换它的左右子树得到:

      8
    /  \
  10    6
 /\      /\
9  11  5  7

我们发现两个结点6和10的左右子树仍然是左结点的值小于右结点的值,我们再试着交换他们的左右子树,得到:

      8
    /  \
  10    6
 /\      /\
11  9  7   5

刚好就是要求的输出。

上面的分析印证了我们的直觉:在遍历二元查找树时每访问到一个结点,交换它的左右子树。这种思路用递归不难实现,将遍历二元查找树的代码稍作修改就可以了。参考代码如下:

///////////////////////////////////////////////////////////////////////
// Mirror a BST (swap the left right child of each node) recursively
// the head of BST in initial call
///////////////////////////////////////////////////////////////////////
void MirrorRecursively(BSTreeNode *pNode)
{
      if(!pNode)
            return;

      // swap the right and left child sub-tree
      BSTreeNode *pTemp = pNode->m_pLeft;
      pNode->m_pLeft = pNode->m_pRight;
      pNode->m_pRight = pTemp;

      // mirror left child sub-tree if not null
      if(pNode->m_pLeft)
            MirrorRecursively(pNode->m_pLeft);  

      // mirror right child sub-tree if not null
      if(pNode->m_pRight)
            MirrorRecursively(pNode->m_pRight);
}

 得出求一棵树的镜像的过程:先前序遍历这棵树的每个结点,如果遍历到的结点有子结点,就交换它的两个子结点。当交换完所有非叶子结点的左右结点之后,就得到了树的镜像。

 

由于递归的本质是编译器生成了一个函数调用的,因此用循环来完成同样任务时最 简单的办法就是用一个辅助栈来模拟递归。首先我们把树的头结点放入栈中。在循环中,只要栈不为空,弹出栈的栈顶结点,交换它的左右子树。如果它有左子树, 把它的左子树压入栈中;如果它有右子树,把它的右子树压入栈中。这样在下次循环中就能交换它儿子结点的左右子树了。参考代码如下:

///////////////////////////////////////////////////////////////////////
// Mirror a BST (swap the left right child of each node) Iteratively
// Input: pTreeHead: the head of BST
///////////////////////////////////////////////////////////////////////
void MirrorIteratively(BSTreeNode *pTreeHead)
{
      if(!pTreeHead)
            return;

      std::stack<BSTreeNode *> stackTreeNode;
      stackTreeNode.push(pTreeHead);

      while(stackTreeNode.size())
      {
            BSTreeNode *pNode = stackTreeNode.top();
            stackTreeNode.pop();

            // swap the right and left child sub-tree
            BSTreeNode *pTemp = pNode->m_pLeft;
            pNode->m_pLeft = pNode->m_pRight;
            pNode->m_pRight = pTemp;

            // push left child sub-tree into stack if not null
            if(pNode->m_pLeft)
                  stackTreeNode.push(pNode->m_pLeft);

            // push right child sub-tree into stack if not null
            if(pNode->m_pRight)
                  stackTreeNode.push(pNode->m_pRight);
      }
}

 

来源:http://zhedahht.blog.163.com/blog/static/2541117420072159363370/

img_e00999465d1c2c1b02df587a3ec9c13d.jpg
微信公众号: 猿人谷
如果您认为阅读这篇博客让您有些收获,不妨点击一下右下角的【推荐】
如果您希望与我交流互动,欢迎关注微信公众号
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

目录
相关文章
|
27天前
|
算法
数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)
数据结构和算法学习记录——层序遍历(层次遍历)、二叉树遍历的应用(输出二叉树中的叶节点、求二叉树的高度、二元运算表达式树及其遍历、由两种遍历序列确定二叉树)
17 0
|
11月前
|
算法 C语言 C++
【树】你真的会二叉树了嘛? --二叉树LeetCode专题Ⅲ
这题算是简单题,我们依然从最简单的情况来考虑。
42 0
|
11月前
|
算法
算法训练Day21|530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 236. 二叉树的最近公共祖先
算法训练Day21|530.二叉搜索树的最小绝对差 ● 501.二叉搜索树中的众数 ● 236. 二叉树的最近公共祖先
|
11月前
|
算法
算法训练Day23|669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树
算法训练Day23|669. 修剪二叉搜索树 ● 108.将有序数组转换为二叉搜索树 ● 538.把二叉搜索树转换为累加树
(Java)二叉树的相关OJ题(相同的树,另一颗树的子树,对称二叉树或镜像二叉树,根据二叉树创建字符串)(内附OJ链接)
给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。
(Java)二叉树的相关OJ题(相同的树,另一颗树的子树,对称二叉树或镜像二叉树,根据二叉树创建字符串)(内附OJ链接)
|
存储
二叉树的性质
二叉树的性质
118 0
二叉树的性质
|
存储 算法 C++
|
存储 机器学习/深度学习
树、二叉树和森林的表示及相互转换
树、二叉树和森林的表示及相互转换
228 0
树、二叉树和森林的表示及相互转换
|
算法 C语言
Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现
Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现
Algorithm:树相关算法(BBT/BST/B树/R树)简介(二叉查找树、二叉查找树的插入节点、二叉查找树的删除、二叉树的遍历、平衡二叉树)C 语言实现