AcWing 49. 二叉搜索树与双向链表(前驱后继+中序遍历)

1.利用前驱后继

对于一个二叉树,可以将其分为左子树、根节点和右子树三部分。根据题目要求可知将BST化为一个排好序的双向链表实际上就是将其中序遍历序列对应的各个节点连接起来。同时还可以知道若根的左右子树非空,则根节点在链表中的前驱结点一定在其左子树中,后继结点一定在其右子树中。那么可以先找到并标记根节点的前驱和后继,然后连接。同时递归执行这一过程便能达到要求。

具体代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *findPreNode(TreeNode *root){
        TreeNode *p = root;
        if(p -> left){
            p = p -> left;
            while(p -> right) p = p -> right;
            return p;
        }
        else return NULL;
    }
    
    TreeNode *findSuccNode(TreeNode *root){
        TreeNode *p = root;
        if(p -> right){
            p = p -> right;
            while(p -> left) p = p -> left;
            return p;
        }
        else return NULL;
    }
    
    TreeNode *change(TreeNode * root){
        TreeNode *p = findPreNode(root); //记录前驱节点指针
        TreeNode *q = findSuccNode(root); //记录后继节点指针
        if(root -> left) change(root -> left);
        if(root -> right) change(root -> right);
        //将当前节点分别与其前驱节点和后继节点相连
        root -> left = p;
        if(p) p -> right = root;
        root -> right = q;
        if(q) q -> left = root;
        return root;
    }
    
    TreeNode* convert(TreeNode* root) {
        if(!root) return NULL;
        change(root);
        while(root -> left) root = root -> left;
        return root;
    }
};

2.中序遍历

可以发现对于一棵BST而言,中序遍历的当前节点与将要回溯的节点之间就是双向链表中相邻的关系。因此可以考虑通过中序遍历来直接完成BST到链表的转化。

具体代码如下:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode(int x) : val(x), left(NULL), right(NULL) {}
 * };
 */
class Solution {
public:
    TreeNode *change(TreeNode *root, TreeNode *&head, TreeNode *&tail){
        if(!root) return NULL;
        change(root -> left, head, tail);
        if(!head){
            head = tail = root;
        }
        else{
            root -> left = tail;
            tail -> right = root;
            tail = root;
        }
        change(root -> right, head, tail);
        return head;
    }

    TreeNode* convert(TreeNode* root) {
        TreeNode *head = NULL, *tail = NULL; //注意这里要么在传参时使用指针引用要么将head和tail声明为全局变量
        return change(root, head, tail);
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值