题目
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。
要求不能创建任何新的结点,只能调整树中结点指针的指向。
注意:
需要返回双向链表最左侧的节点。
例如,输入下图中左边的二叉搜索树,则输出右边的排序双向链表。
二叉搜索树与双向链表 - 图1

解法一:后序遍历

先获取左子树最右结点和右子树最左结点,然后进行拼接
时间复杂度O(n),空间复杂度O(1)

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. TreeNode* convert(TreeNode* root) {
  13. if (!root) return nullptr;
  14. auto ans = dfs(root);
  15. return ans.first;
  16. }
  17. pair<TreeNode*, TreeNode*> dfs(TreeNode* u) {
  18. if (!u->left && !u->right) return {u, u};
  19. else if (u->left && u->right) {
  20. auto l = dfs(u->left), r = dfs(u->right);
  21. l.second->right = u, u->left = l.second;
  22. u->right = r.first, r.first->left = u;
  23. return {l.first, r.second};
  24. }
  25. else if (u->left) {
  26. auto l = dfs(u->left);
  27. l.second->right = u, u->left = l.second;
  28. return {l.first, u};
  29. }
  30. else {
  31. auto r = dfs(u->right);
  32. u->right = r.first, r.first->left = u;
  33. return {u, r.second};
  34. }
  35. }
  36. };

解法二:逆中序遍历

从大往小遍历与拼接,用一个指针维护当前值最小的结点,遍历结束后,该指针即为二叉链表起点
时间复杂度O(n),空间复杂度O(1)

  1. /**
  2. * Definition for a binary tree node.
  3. * struct TreeNode {
  4. * int val;
  5. * TreeNode *left;
  6. * TreeNode *right;
  7. * TreeNode(int x) : val(x), left(NULL), right(NULL) {}
  8. * };
  9. */
  10. class Solution {
  11. public:
  12. TreeNode* convert(TreeNode* root) {
  13. if (!root) return nullptr;
  14. TreeNode *last = nullptr;
  15. dfs(root, last);
  16. return last;
  17. }
  18. void dfs(TreeNode* u, TreeNode* &f) {
  19. if (!u) return;
  20. if (u->right) dfs(u->right, f);
  21. u->right = f;
  22. if (f) f->left = u;
  23. f = u;
  24. if (u->left) dfs(u->left, f);
  25. }
  26. };