BST树转双向链表,保证链表有序

在处理二叉树的过程中,对于二叉树指向问题一直是比较棘手的问题,常见做法就是将二叉树用(前中后层序)遍历的形式进行转换,对于较为复杂的问题,如何去解决呢?
我们介绍到一种分治思想

问题:输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
这个问题如果我们去研究更改指向的规律,很容易将我们自身绕进去。
在这里插入图片描述
我们给定一个这样的BST树,如果我们来研究如何将其更改指向到接下来这张图
在这里插入图片描述
我们是无法通过找规律旋转出来的。
但是我们会一种做法:

中序遍历

我们可以用一个容器,将遍历后的结果放到一个容器里面,然后对这个容器进行操作,就能得到一个想要的链表。来看代码:

void Inorder(TreeNode* root, vector<TreeNode*> & vec)
{
    if(root == nullptr)
    {
        return;
    }
    else
    {
        Inorder(root-> left,vec);
        vec.push_back(root);
        Inorder(root->right,vec);
    }
}
class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree) {
    if(nullptr == pRootOfTree)
    {
        return nullptr;
    }
    vector<TreeNode*> vec;
        Inorder(pRootOfTree,vec);
    if(vec.size() == 1)
    {return vec[0];}   
            for(size_t i = 1;i < vec.size() - 1;++i)
    {
        vec[i]->left = vec[i-1];
        vec[i]->right = vec[i+1];
    }
        vec[0]->right = vec[1];
        vec[vec.size() - 1]->left = vec[vec.size() - 2];
        vec[vec.size() - 1]->right = NULL;
        return vec[0];
    }
};

另一种做法:

分治

我们无法得知全部实现转换,但是我们可以实现部分。

我们可以保证每一个节点都是满足这个情况
在这里插入图片描述


class Solution {
public:
    void Convert(TreeNode* Root , TreeNode*& prev)
    {
       if(nullptr == Root)
       {
           return;
       }
        Convert(Root->left, prev);
        Root->left = prev;
        if(prev)
        {
            prev->right = Root;
        }
        prev = Root;
        Convert(Root->right,prev);
    }
    TreeNode* Convert(TreeNode* pRootOfTree) {
    if(pRootOfTree == nullptr)
    {
        return nullptr;
    }
    TreeNode* head = pRootOfTree;
        while(head->left)
        {
            head = head->left;
        }
      TreeNode* prev = nullptr;
      Convert(pRootOfTree, prev);
      return head;
    }
};

我在当时看完别人所写的分治代码后很不明白为啥这个prev初始化是nullptr,如果是让这个prev表示前一个节点,那么这个root对应的前一个节点是nullptr,所写代码应该是

if(prev)
prev->left = root;

但是我们来看这个代码:

  Convert(Root->left, prev);

这行代码会一直递归走到最左边的节点,直到这个节点为NULL。
然后回退到最左边那个节点,此时prev表示root上一步的节点,也就是说root的上一步的节点为nulltptr,这也就是为什么这个prev不能随便初始化的原因。这个prev是需要进行考虑初始化的,并不是随便的赋值。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值