题目:
输入一棵二叉搜索树,将该二叉搜索树转换成一个排序的双向链表。要求不能创建任何新的结点,只能调整树中结点指针的指向。
分析:
创建两个指针,分别指向要处理的当前元素和当前元素的前一个元素。利用中序遍历找到二叉树中最小的元素,实际上也是双向链表的最左端的值。依次将当前元素和前一个元素用left和right连接起来,在处理右子树之前,要将前一个元素改成当前的元素,以便后续元素的处理。如图:
图出自:https://www.jianshu.com/p/7607d8519c59
当然还可以根据中序遍历,将所有节点存储起来,然后再重新按顺序连接所有节点,因为中序遍历的节点已经有序,直接前后相连即可。
程序:
C++
class Solution { public: TreeNode* Convert(TreeNode* pRootOfTree) { if(pRootOfTree == nullptr) return nullptr; if(pRootOfTree->left == nullptr && pRootOfTree->right == nullptr) return pRootOfTree; helper(pRootOfTree); for(int i = 0; i < node.size()-1; ++i){ node[i]->right = node[i+1]; node[i+1]->left = node[i]; } return node[0]; } void helper(TreeNode* root){ if(root == nullptr) return; helper(root->left); node.push_back(root); helper(root->right); } private: vector<TreeNode*> node; };
class Solution { public: TreeNode* Convert(TreeNode* pRootOfTree) { if(pRootOfTree == nullptr) return nullptr; if(pRootOfTree->left == nullptr && pRootOfTree->right == nullptr) return pRootOfTree; TreeNode* pre = nullptr; helper(pRootOfTree, pre); while(pRootOfTree->left != nullptr){ pRootOfTree = pRootOfTree->left; } return pRootOfTree; } void helper(TreeNode* cur, TreeNode* &pre){ if(cur == nullptr) return; if(cur->left != nullptr) helper(cur->left, pre); cur->left = pre; if(pre != nullptr) pre->right = cur; pre = cur; if(cur->right != nullptr){ helper(cur->right, pre); } } };
Java
public class Solution { public TreeNode Convert(TreeNode pRootOfTree) { if(pRootOfTree == null) return null; if(pRootOfTree.left == null && pRootOfTree.right == null) return pRootOfTree; //TreeNode pre = null; helper(pRootOfTree); while(pRootOfTree.left != null){ pRootOfTree = pRootOfTree.left; } return pRootOfTree; } public void helper(TreeNode cur){ if(cur == null) return; if(cur.left != null) helper(cur.left); cur.left = pre; if(pre != null) pre.right = cur; pre = cur; if(cur.right != null){ helper(cur.right); } } private TreeNode pre = null; }