# [114. Flatten Binary Tree to Linked List](https://leetcode.com/problems/flatten-binary-tree-to-linked-list/) # 思路 要求把二叉树展开成链表,根据例子可以看到是先序遍历的顺序。 ## 思路一 最容易想到的就是先序遍历一遍树。我们可以用一个全局的指针`list_last`记录当前链表的最后一个节点,每遍历到一个节点就将其接到`list_last`后面(右指针)。 ## 思路二* 此题也可以直接递归来做。即如果root的左右子树都已经是被展开好的,那么只需要将左子树接在root的右边,再将右子树接在原来左子树的最下边就可以了,如下例。 ``` 1 1 / \ \ 2 5 ===> 2 \ \ \ 3 6 3 \ \ 4 4 \ 5 \ 6 ``` ## 思路三* 可以将思路二改成非递归版本。原理类似:当前工作指针p指向root,如果p有左子树,那么将其左子树接在p的右边,而原来的右子树接在左子树的最右下边节点,此为一次循环,然后工作指针p向右下移动一步,重复上述操作。下面举个例子: ``` 原二叉树: 1 / \ 2 5 / \ \ 3 4 6 第一次工作指针p指向1,循环后: 1 \ 2 / \ 3 4 \ 5 \ 6 第二次工作指针p指向2,循环后: 1 \ 2 \ 3 \ 4 \ 5 \ 6 接下来每次循环p依次指向3、4、5、6,由于p没有左子树,所以不作任何操作。 ``` # C++ ## 思路一 ``` C++ class Solution { private: TreeNode *list_last = NULL; void helper(TreeNode *root){ // 先序遍历 if(root == NULL) return; if(list_last != NULL) // 不是第一个 list_last -> right = root; list_last = root; // 由于后面要将左右指针置空,所以这里先记录一下 TreeNode *left = root -> left; TreeNode *right = root -> right; root -> left = NULL; root -> right = NULL; helper(left); helper(right); } public: void flatten(TreeNode* root) { if(root == NULL) return; list_last = NULL; helper(root); } }; ``` ## 思路二 ``` C++ class Solution { public: void flatten(TreeNode* root) { if(root == NULL) return; // 递归出口 flatten(root -> left); flatten(root -> right); TreeNode *right = root -> right; // 先备份右子树 root -> right = root -> left; // 将左子树放在右边 root -> left = NULL; TreeNode *tmp = root; // 一路下降到最下面 while(tmp -> right) tmp = tmp -> right; tmp -> right = right; } }; ``` ## 思路三 ``` C++ class Solution { public: void flatten(TreeNode* root) { TreeNode *p = root; while(p){ if(p -> left){ // 先备份右子树 TreeNode *right_bk = p -> right; p -> right = p -> left; p -> left = NULL; TreeNode *tmp = p; while(tmp -> right) tmp = tmp -> right; // 此时tmp指向p原来左子树的最右下节点 tmp -> right = right_bk; } p = p -> right; } } }; ```