zoukankan      html  css  js  c++  java
  • (剑指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;
        }
    
    };
  • 相关阅读:
    P4839 P哥的桶 题解(线段树维护线性基)
    线性基入门
    Lowest Common Ancestor 题解(lca+思维)
    B
    java string对象的简单方法
    AtCoder Grand Contest 016 D
    FFT
    回文自动机(BZOJ2565)
    二维RMQ
    AC自动机(BZOJ1030)
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4655018.html
Copyright © 2011-2022 走看看