(剑指Offer)面试题27:二叉搜索树与双向链表

题目:

输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。

二叉树的定义如下:

struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
};

思路:

在二叉树中,每个结点都有两个指向子结点的指针,在双向链表中,每个结点也有两个指针,他们分别指向前一个结点和后一个结点。两种数据结构看起来很相似,是可以通过某种方式将二叉搜索树转换为排序的双向链表。

在二叉搜索树中,当遍历到根结点时,把二叉树看成三部分,根结点、左子树和右子树,根据排序链表的定义,根结点的左指针应该指向左子树中最大的结点,即最右边的结点;根结点的右指针应该指向右子树中最小的结点,即最左边的结点。

在把左子树、右子树都转换成排序的双向排序链表(递归)之后,再跟根结点连接起来,整棵二叉搜索树就转换成了排序的双向链表。

因此在设计递归函数时,需要返回链表的头指针和尾指针,并改变当前结点的左右指针的指向。(详见代码)

代码:

#include <iostream>

using namespace std;

struct TreeNode{
    int val;
    TreeNode* left;
    TreeNode* right;
};

TreeNode* ConvertNodes(TreeNode* pRoot,TreeNode** pTail);

TreeNode* Convert(TreeNode* pRoot){
    TreeNode* pTail=NULL;
    return ConvertNodes(pRoot,&pTail);
}

TreeNode* ConvertNodes(TreeNode* pRoot,TreeNode** pTail){
    if(pRoot==NULL)
        return NULL;
    if(pRoot->left==NULL && pRoot->right==NULL){
        *pTail=pRoot;
        return pRoot;
    }
    TreeNode* leftHead=pRoot;
    if(pRoot->left!=NULL){
        leftHead=ConvertNodes(pRoot->left,pTail);
        pRoot->left=*pTail;
        if(*pTail!=NULL)
            (*pTail)->right=pRoot;
        *pTail=pRoot;
    }

    if(pRoot->right!=NULL){
        TreeNode* rightHead=ConvertNodes(pRoot->right,pTail);
        pRoot->right=rightHead;
        if(rightHead!=NULL)
            rightHead->left=pRoot;
    }
    return leftHead;
}

在线测试OJ:

http://www.nowcoder.com/books/coding-interviews/947f6eb80d944a84850b0538bf0ec3a5?rp=2

AC代码:

class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        TreeNode* pTail=NULL;
        return ConvertNodes(pRootOfTree,&pTail);
    }

    TreeNode* ConvertNodes(TreeNode* pRoot,TreeNode** pTail){
        if(pRoot==NULL)
            return NULL;
        if(pRoot->left==NULL && pRoot->right==NULL){
            *pTail=pRoot;
            return pRoot;
        }

        TreeNode* leftHead=pRoot;
        if(pRoot->left!=NULL){
            leftHead=ConvertNodes(pRoot->left,pTail);
            pRoot->left=*pTail;
            if(*pTail!=NULL)
                (*pTail)->right=pRoot;
            *pTail=pRoot;
        }

        if(pRoot->right!=NULL){
            TreeNode* rightHead=ConvertNodes(pRoot->right,pTail);
            pRoot->right=rightHead;
            if(rightHead!=NULL)
                rightHead->left=pRoot;
        }
        return leftHead;
    }

};
posted @ 2015-07-17 16:42  AndyJee  阅读(535)  评论(0编辑  收藏  举报