何海涛算法面试题感悟之一:将二叉…

题目:输入一棵二元查找树,将该二元查找树转换成一个排序的双向链表。要求不能创建任何新的结点,只调整指针的指向。

  比如将二元查找树
   
                                        10
                                            \
                                             14
                                         /  \
                                    4     12    16
转换成双向链表

4=6=8=10=12=14=16

思路之一是用递归的思想,先将左子数转为为左双向链表,并且连接到根节点,然后再将右子数转换为右双向链表,并且链接到根节点,最后,如果该根节点是原来整个树中的右子树的根,那么返回的双向链表的头指针应该是最左的节点(最小的节点),这样才能使该节点正确地链接到整个数中的根节点的下一个节点,如果该根节点是原来整个数中的左子数的根,那么返回的双向链表的头指针应该是最右的节点(最大的节点),这样才能使该节点正确地链接到整个数中的根节点的下一个节点.于是,就可以根据此思想写出c++源码了.

先定义数据结构

struct BSTreeNode //二分查找树中的一个节点
    {
        int          m_nValue; // 节点的值
        BSTreeNode  *m_pLeft;  // 左指针域
        BSTreeNode  *m_pRight; // 右指针域
    };

然后,我们就可以根据以上递归的思想一步一步写出c++源码了

BSTreeNode* ConvertNode(BSTreeNode* pNode, bool asRight)
   //如果是空数,那么返回空指针
      if(!pNode)
            return NULL;
     //定义两个指针,存放当前节点的左双向链表的根河和右双向链表的根
      BSTreeNode *pLeft = NULL;
      BSTreeNode *pRight = NULL;

      //先将左子数转换为双向链表,注意这里的第二个参数是false,表示左子数节点转换为左双向链表
      if(pNode->m_pLeft)
            pLeft = ConvertNode(pNode->m_pLeft, false);

      //如果左双向链表不为空,那么就正确地链接到当前节点pNode上
      if(pLeft)
      {
            pLeft->m_pRight = pNode;
            pNode->m_pLeft = pLeft;
      }

      //再将右子数转换为双向链表,注意这里的第二个参数是true,表示右子数节点转换为右双向链表
      if(pNode->m_pRight)
            pRight = ConvertNode(pNode->m_pRight, true);

      //如果右双向链表不为空,那么就正确地链接到当前节点pNode上
      if(pRight)
      {
            pNode->m_pRight = pRight;
            pRight->m_pLeft = pNode;
      }
    
//到了这里,当前节点pNode以及它的子数已经被转换为双向链表了,最后一步,就是怎样将转换好的双向链表的头指针返回呢?显然,我们应该根据当前节点在原子数中的位置判断,如果当前节点pNode在原来的树种是以右节点的形式存在的,那么以当前节点为头指针的双向链表应该返回整个以pNode为根节点的子数中最小的节点,也即最左的节点,反之,则返回最右的节点,以下代码便是这段文字的代码描述
      BSTreeNode *pTemp = pNode;
      if(asRight)
      {
            while(pTemp->m_pLeft)
                  pTemp = pTemp->m_pLeft;
      }
      else
      {
            while(pTemp->m_pRight)
                  pTemp = pTemp->m_pRight;
      }
      return pTemp;
}

最后,我们就可以用一个主函数来对以上一段程序进行包装,以形成一个独立功能的函数

BSTreeNode* Convert(BSTreeNode* pHeadOfTree)
{
      //这里,第二个参数为true,即把整个树当做是右子数看待,这样,最终就能返回整个树中的最小的节点了.
      return ConvertNode(pHeadOfTree, true);
}


本题对应何海涛博客

http://zhedahht.blog.163.com/blog/static/254111742007127104759245/



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值