剑指offer:二叉搜索树与双向链表

 

题目描述

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

思路:模拟中序遍历的过程就OK,或者利用分治的思想,递归分别处理左右子树,再合并左右子树成一条链。

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    TreeNode* hd = NULL, *pre = NULL;
    void dfs(TreeNode* rt){
        if(rt->left) dfs(rt->left);
        rt->left = pre;
        if(hd == NULL) hd = rt;
        if(pre) pre->right = rt;
        pre = rt;
        if(rt->right) dfs(rt->right);
    }
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        if(pRootOfTree == NULL) return NULL;
        dfs(pRootOfTree);
        return hd;
    }
};
/*
struct TreeNode {
    int val;
    struct TreeNode *left;
    struct TreeNode *right;
    TreeNode(int x) :
            val(x), left(NULL), right(NULL) {
    }
};*/
class Solution {
public:
    pair<TreeNode*, TreeNode*> dfs(TreeNode* rt){
        pair<TreeNode*, TreeNode*>res = make_pair(rt, rt);
        if(rt->left == NULL && rt->right == NULL) return res;
        if(rt->left == NULL){
            pair<TreeNode*, TreeNode*>rgt = dfs(rt->right);
            rgt.first->left = rt;
            rt->right = rgt.first;
            rgt.first = rt;
            return rgt;
        }
        if(rt->right == NULL){
            pair<TreeNode*, TreeNode*>lft = dfs(rt->left);
            lft.second->right = rt;
            rt->left = lft.second;
            lft.second = rt;
            return lft;
        }
        pair<TreeNode*, TreeNode*>lft = dfs(rt->left);
        pair<TreeNode*, TreeNode*>rgt = dfs(rt->right);
        lft.second->right = rt;
        rt->left = lft.second;
        rgt.first->left = rt;
        rt->right = rgt.first;
        return make_pair(lft.first, rgt.second);
    }
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        if(pRootOfTree == NULL) return NULL;
        pair<TreeNode*, TreeNode*>ans = dfs(pRootOfTree);
        ans.first->left = NULL;
        ans.second->right = NULL;
        return ans.first;
    }
};

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值