# [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;
        }
    }
};
```