/*
struct TreeNode {
int val;
struct TreeNode *left;
struct TreeNode *right;
TreeNode(int x) :
val(x), left(NULL), right(NULL) {
}
};*/
class Solution {
public:
TreeNode* Convert(TreeNode* pRootOfTree) {
if (pRootOfTree == nullptr) return nullptr;
TreeNode* pre = nullptr;
// 中序遍历并调整指针
inorder(pRootOfTree, pre);
// 找到链表的头节点(最左边的节点)
TreeNode* head = pRootOfTree;
while (head->left != nullptr) {
head = head->left;
}
return head;
}
private:
void inorder(TreeNode* root, TreeNode*& pre) {
if (root == nullptr) return;
// 遍历左子树
inorder(root->left, pre);
// 处理当前节点
// 将当前节点的左指针指向前驱节点
root->left = pre;
// 如果前驱节点存在,将前驱节点的右指针指向当前节点
if (pre != nullptr) {
pre->right = root;
}
// 更新前驱节点为当前节点
pre = root;
// 遍历右子树
inorder(root->right, pre);
}
};
思路1:已知将二叉搜索树进行中序遍历可以得到由小到大的顺序排列,因此本题最直接的想法就是进行中序遍历。
将中序遍历的结果用数组存储下来,得到的数组是有从小到大顺序的。最后将数组中的结点依次连接即可。
思路2:二叉搜索树的中序遍历是有序的,所以我们需要利用中序遍历来调整指针指向。关键是在遍历过程中维护一个前驱节点,将当前节点与前驱节点连接起来。
二叉搜索树转换成一个排序的双向链表的思路都离不开中序遍历,两个思路的差别是时间复杂度不同