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

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

题目描述

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

解题思路

一开始苦思冥想,无果。然后看书上的一图得到启发,如下。
在这里插入图片描述
即先保存根的左右子树,对于根结点的左子树,如果左子树的右子树不等于根结点(即没有修改过),查找左子树里最右端的结点,将这个结点的右子树修改为根结点,根结点的左子树修改为这个结点;对于根结点的右子树,如果右子树的左子树不等于根结点(即没有修改过),查找右子树最左端的结点,将这个结点的左子树修改为根结点,再将根结点的右子树修改为这个结点。递归之前保存的根结点的左右子树。特别要注意加粗的文字,避免程序陷入死循环的办法。

Code

/*
struct TreeNode {
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x) :
			val(x), left(NULL), right(NULL) {
	}
};*/
class Solution {
public:
    TreeNode* FindRightestNode(TreeNode* pRoot) {
        if(!pRoot) return nullptr;
        TreeNode* rightestNode = pRoot;
        if(pRoot->right) {
            return FindRightestNode(pRoot->right);
        }
        return pRoot;
    }
    TreeNode* FindLeftestNode(TreeNode* pRoot) {
        if(!pRoot) return nullptr;
        TreeNode* leftestNode = pRoot;
        if(pRoot->left) {
            return FindLeftestNode(pRoot->left);
        }
        return pRoot;
    }
    void ConvertCore(TreeNode* pRoot) {
        if(!pRoot) return ;
        if(pRoot->left) {
            if(pRoot->right) {
                if(pRoot->left->right == pRoot && pRoot->right->left == pRoot) return ;
            } else {
                if(pRoot->left->right == pRoot) return ;
            }
        } else {
            if(pRoot->right) {
                if(pRoot->right->left == pRoot) return ;
            }
        }
        
        TreeNode *pLeftestNode =  nullptr, *pRightestNode = nullptr;
        TreeNode *pLeft = pRoot->left, *pRight = pRoot->right;
        if(pRoot->left && pRoot->left->right != pRoot) {
            //如果左子树的右子树是当前结点的话则不用换,否则程序会陷入死循环
            pRightestNode = FindRightestNode(pRoot->left);
            pRightestNode->right = pRoot;
            pRoot->left = pRightestNode;
        }
        if(pRoot->right && pRoot->right->left != pRoot) {
            //如果左子树的右子树是当前结点的话则不用换,否则程序会陷入死循环
            pLeftestNode = FindLeftestNode(pRoot->right);
            pRoot->right = pLeftestNode;
            pLeftestNode->left = pRoot;
        }
        if(pLeft) {
            ConvertCore(pLeft);
        }
        if(pRight) {
            ConvertCore(pRight);
        }
    }
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        if(!pRootOfTree) {
            return nullptr;
        }
        ConvertCore(pRootOfTree);
        return FindLeftestNode(pRootOfTree);
    }
};
  • java1
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public void ConvertCore(TreeNode pRootOfTree) {
        if(pRootOfTree == null || (pRootOfTree.left == null && pRootOfTree.right == null)) return ;
        else if(pRootOfTree.right != null  && pRootOfTree.right.left == pRootOfTree) {
            if(pRootOfTree.left == null || (pRootOfTree.left.right == pRootOfTree)) return;
        } else if(pRootOfTree.left != null && pRootOfTree.left.right == pRootOfTree) {
            if(pRootOfTree.right == null) return;
        }
        TreeNode left = pRootOfTree.left, right = pRootOfTree.right;
        TreeNode pre = left, post = right;
        if(left != null && left.right != pRootOfTree) {
            while(pre.right != null) {
                pre = pre.right;
            }
            pre.right = pRootOfTree;
            pRootOfTree.left = pre;
        }
        if(right != null && right.left != pRootOfTree) {
            while(post.left != null) {
                post = post.left;
            }
            post.left = pRootOfTree;
            pRootOfTree.right = post;
        }
        ConvertCore(left);
        ConvertCore(right);
    }
    public TreeNode Convert(TreeNode pRootOfTree) {
        ConvertCore(pRootOfTree);
        TreeNode root = pRootOfTree;
        while(root != null && root.left != null) {
            root = root.left;
        }
        return root;
    }
}
  • java
/**
public class TreeNode {
    int val = 0;
    TreeNode left = null;
    TreeNode right = null;

    public TreeNode(int val) {
        this.val = val;

    }

}
*/
public class Solution {
    public TreeNode Convert(TreeNode pRootOfTree) {
        if(pRootOfTree == null || (pRootOfTree.left == null && pRootOfTree.right == null)) return pRootOfTree;
        TreeNode left = Convert(pRootOfTree.left);
        TreeNode pre = left;
        while(pre != null && pre.right != null) {
            pre = pre.right;
        }
        if(pre != null) {
            pre.right = pRootOfTree;
            pRootOfTree.left = pre;
        }
        TreeNode post = Convert(pRootOfTree.right);
        if(post != null) {
            post.left = pRootOfTree;
            pRootOfTree.right = post;
        }
        return left == null ? pRootOfTree : left;
    }
}
  • 评论区的代码
//链接:https://www.nowcoder.com/questionTerminal/947f6eb80d944a84850b0538bf0ec3a5
//来源:牛客网

class Solution {
public:
    TreeNode* Convert(TreeNode* pRootOfTree)
    {
        if(pRootOfTree == nullptr) return nullptr;
        TreeNode* pre = nullptr;
         
        convertHelper(pRootOfTree, pre);
         
        TreeNode* res = pRootOfTree;
        while(res ->left)
            res = res ->left;
        return res;
    }
     
    void convertHelper(TreeNode* cur, TreeNode*& pre)
    {
        if(cur == nullptr) return;
         
        convertHelper(cur ->left, pre);
         
        cur ->left = pre;
        if(pre) pre ->right = cur;
        pre = cur;
         
        convertHelper(cur ->right, pre);
         
         
         
    }
};

总结

  • java中的引用是地址,它指向了对象,有点像c++的指针
  • 直接用中序遍历更不容易出错
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值