题解 | #二叉搜索树与双向链表#
二叉搜索树与双向链表
https://www.nowcoder.com/practice/947f6eb80d944a84850b0538bf0ec3a5
/* struct TreeNode { int val; struct TreeNode *left; struct TreeNode *right; TreeNode(int x) : val(x), left(NULL), right(NULL) { } };*/ #include <ios> #include <utility> #include <vector> class Solution { public: TreeNode* Convert(TreeNode* root) { if(root == nullptr) return nullptr; TreeNode* Left = Convert(root->left,root).second; TreeNode* Right = Convert(root->right,root).first; if(Left!=nullptr){ root->left = Left; Left->right = root; } if(Right!=nullptr){ root->right = Right; Right->left = root; } //cout<<root->right->val<<endl; while(root->left!=nullptr) root = root->left; return root; } pair<TreeNode*,TreeNode*> Convert(TreeNode* root, TreeNode* father){ pair<TreeNode*,TreeNode*> resultLeft; pair<TreeNode*,TreeNode*> resultRight; if(root==nullptr) return make_pair(nullptr, nullptr); TreeNode* MinNode = nullptr; TreeNode* MaxNode = nullptr; if(root->left!=nullptr){ resultLeft = Convert(root->left,root); MinNode = resultLeft.first; root->left = resultLeft.second; resultLeft.second->right = root; } else{ MinNode = root; if(root==father->right) root->left = father; } if(root->right!=nullptr){ resultRight = Convert(root->right,root); MaxNode = resultRight.second; root->right = resultRight.first; resultRight.first->left = root; } else{ MaxNode = root; if(root==father->left) root->right = father; } return make_pair(MinNode, MaxNode); } };
基本思路就是完成一个递归函数,功能是同时返回当前结点为根结点的树的最小结点和最大结点,同时将该输入结点的前驱和后继修改为题目要求的。要注意每个方向的递归调用只能执行一次,因为执行之后它的左子树内部结点的前驱和后继都已经修改完了,因此不能执行第二次。需要注意的地方就是当某一边子树为空时,要考虑前驱或者后继可能是父亲结点的情况。比如当前结点是父节点的左子树,且自己没有右子树,则说明父节点是该结点的后继。
其实最核心的点就是,每次遍历一个结点,既需要得到它左子树的最小结点(因为它自己的最小结点就是它左子树的最小结点),又需要它左子树的最大结点(作为自己结点的前驱)。但是它左子树只能遍历一遍,因此函数必须同时返回最大和最小。