LeetCode(114): 二叉树展开为链表

Medium!

题目描述:

给定一个二叉树,原地将它展开为链表。

例如,给定二叉树

    1
   / 
  2   5
 /    
3   4   6

将其展开为:

1
 
  2
   
    3
     
      4
       
        5
         
          6

解题思路:

这道题要求把二叉树展开成链表,根据展开后形成的链表的顺序分析出是使用先序遍历,那么只要是数的遍历就有递归和非递归的两种方法来求解,这里我们也用两种方法来求解。

首先来看递归版本的,思路是先利用DFS的思路找到最左子节点,然后回到其父节点,把其父节点和右子节点断开,将原左子结点连上父节点的右子节点上,然后再把原右子节点连到新右子节点的右子节点上,然后再回到上一父节点做相同操作。

C++解法一:

 1 // Recursion
 2 class Solution {
 3 public:
 4     void flatten(TreeNode *root) {
 5         if (!root) return;
 6         if (root->left) flatten(root->left);
 7         if (root->right) flatten(root->right);
 8         TreeNode *tmp = root->right;
 9         root->right = root->left;
10         root->left = NULL;
11         while (root->right) root = root->right;
12         root->right = tmp;
13     }
14 };

例如,对于下面的二叉树,上述算法的变换的过程如下:

复制代码
     1
    / 
   2   5
  /    
 3   4   6

     1
    / 
   2   5
       
     3   6
          
       4

   1
    
     2
      
       3
        
         4
          
           5
            
             6
复制代码

下面我们再来看非迭代版本的实现,这个方法是从根节点开始出发,先检测其左子结点是否存在,如存在则将根节点和其右子节点断开,将左子结点及其后面所有结构一起连到原右子节点的位置,把原右子节点连到原左子结点最后面的右子节点之后。

C++解法二:

 1 // Non-recursion
 2 class Solution {
 3 public:
 4     void flatten(TreeNode *root) {
 5         TreeNode *cur = root;
 6         while (cur) {
 7             if (cur->left) {
 8                 TreeNode *p = cur->left;
 9                 while (p->right) p = p->right;
10                 p->right = cur->right;
11                 cur->right = cur->left;
12                 cur->left = NULL;
13             }
14             cur = cur->right;
15         }
16     }
17 };

例如,对于下面的二叉树,上述算法的变换的过程如下:

复制代码
     1
    / 
   2   5
  /    
 3   4   6

   1
    
     2
    / 
   3   4
        
         5
          
           6
           
   1
    
     2
      
       3
        
         4
          
           5
            
             6
复制代码

前序迭代解法如下:

C++解法三:

 1 class Solution {
 2 public:
 3     void flatten(TreeNode* root) {
 4         if (!root) return;
 5         stack<TreeNode*> s;
 6         s.push(root);
 7         while (!s.empty()) {
 8             TreeNode *t = s.top(); s.pop();
 9             if (t->left) {
10                 TreeNode *r = t->left;
11                 while (r->right) r = r->right;
12                 r->right = t->right;
13                 t->right = t->left;
14                 t->left = NULL;
15             }
16             if (t->right) s.push(t->right);
17         }
18     }
19 };

此题还可以延伸到用中序,后序,层序的遍历顺序来展开原二叉树,分别又有其对应的递归和非递归的方法,有兴趣的童鞋可以自行实现。

原文地址:https://www.cnblogs.com/ariel-dreamland/p/9162548.html