程序员面试题精选100题(11)-求二元查找树的镜像[数据结构]

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

例如输入:

     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

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

      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/

程序员面试题精选100题:41-50解题报告

程序员面试题精选100题(41)-把数组排成最小的数[算法]   题目:输入一个正整数数组,将它们连接起来排成一个数,输出能排出的所有数字中最小的一个。例如输入数组{32,  321},则输出这两个...
  • nanjunxiao
  • nanjunxiao
  • 2013年06月25日 18:18
  • 947

程序员面试题精选100题:51-63解题报告

程序员面试题精选100题(51)-顺时针打印矩阵[算法]   题目:输入一个矩阵,按照从外向里以顺时针的顺序依次打印出每一个数字。 例如:如果输入如下矩阵: 1              2  ...
  • nanjunxiao
  • nanjunxiao
  • 2013年06月26日 00:07
  • 1147

程序员面试题精选100题(59)-字符串的组合[算法]

题目:输入一个字符串,输出该字符串中字符的所有组合。举个例子,如果输入abc,它的组合有a、b、c、ab、ac、bc、abc。 分析:在本系列博客的第28题《字符串的排列》中,我们详细讨论了如何用递...
  • GarfieldEr007
  • GarfieldEr007
  • 2016年02月24日 12:19
  • 1041

程序员面试题精选100题:11-40解题报告

程序员面试题精选100题(11)-求二元查找树的镜像[数据结构]   题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完...
  • nanjunxiao
  • nanjunxiao
  • 2013年06月25日 14:37
  • 1839

[程序员面试题精选100题]58.八皇后问题

题目在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法。...
  • SunnyYoona
  • SunnyYoona
  • 2015年04月04日 22:14
  • 1268

程序员面试题精选(11)-求二元查找树的镜像

程序员面试题精选(11)-求二元查找树的镜像题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。 例如输入:...
  • zjuwispersure
  • zjuwispersure
  • 2010年12月12日 22:24
  • 302

程序员面试题精选(11):求二元查找树的镜像

题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找树中,左子树的结点都大于右子树的结点。用递归和循环两种方法完成树的镜像转换。例如输入:     8    /  /  6      ...
  • yysdsyl
  • yysdsyl
  • 2007年10月24日 14:37
  • 1431

程序员面试题精选100题(58)-八皇后问题[算法]

题目:在8×8的国际象棋上摆放八个皇后,使其不能相互攻击,即任意两个皇后不得处在同一行、同一列或者同一对角斜线上。下图中的每个黑色格子表示一个皇后,这就是一种符合条件的摆放方法。请求出总共有多少种摆法...
  • GarfieldEr007
  • GarfieldEr007
  • 2016年02月24日 12:19
  • 813

程序员面试题精选100题(11)-求二元查找树的镜像

http://zhedahht.blog.163.com/blog/static/2541117420072159363370/  题目:输入一颗二元查找树,将该树转换为它的镜像,即在转换后的二元查找...
  • linxhpku
  • linxhpku
  • 2009年05月04日 13:49
  • 190

程序员面试题100题第11题——求二元查找树的镜像(即交换左右子树)

题目:求二元查找树的镜像(即交换左右子树),递归+迭代 分析:其实操作和前序二叉树类似。 void Mirror(TreeNode *root)//递归互换左右子树 { if(...
  • zjhhust
  • zjhhust
  • 2012年10月04日 21:38
  • 289
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:程序员面试题精选100题(11)-求二元查找树的镜像[数据结构]
举报原因:
原因补充:

(最多只允许输入30个字)