[Leetcode] Flatten Binary Tree to Linked List

Flatten Binary Tree to Linked List 题解

题目来源:https://leetcode.com/problems/


Description

Given a binary tree, flatten it to a linked list in-place.

Example

For example,
Given

         1
        / \
       2   5
      / \   \
     3   4   6

The flattened tree should look like:

   1
    \
     2
      \
       3
        \
         4
          \
           5
            \
             6

Hints:

If you notice carefully in the flattened tree, each node's right child points to the next node of a pre-order traversal.

Solution

class Solution {
private:
    TreeNode* getTail(TreeNode *node) {
        if (node -> left == NULL && node -> right == NULL) {
            return node;
        }
        TreeNode *leftTail = node -> left;
        TreeNode *rightTail = node -> right;
        if (leftTail) {
            leftTail = getTail(leftTail);
            if (rightTail)
                rightTail = getTail(rightTail);
            if (rightTail) {
                leftTail -> right = node -> right;
            }
            node -> right = node -> left;
            node -> left = NULL;
            return rightTail ? rightTail : leftTail;
        }
        return getTail(rightTail);
    }
public:
    void flatten(TreeNode* root) {
        if (root)
            getTail(root);
    }
};

解题描述

这道题题意是,将一棵二叉树变成一个链表,树节点的right指针代表链表节点的next指针,并且要求链表元素顺序是二叉树的前序遍历。同时,要求必须原地操作,也就是只能使用指针操作构造链表,而不能申请额外空间。上面给出的做法是递归前序遍历的做法,不难理解,下面要介绍一种使用Morris遍历变种的办法,不需要使用递归也不需要使用栈来暂存节点,可以说在空间复杂度上做得很好:

class Solution {
public:
    void flatten(TreeNode* root) {
        TreeNode *curNode = root, *preNode = NULL;
        while (curNode) {
            if (curNode -> left) {
                preNode = curNode -> left;
                while (preNode -> right) // 找到左子树链表尾
                    preNode = preNode -> right;

                //此时preNode为curNode左子树链表尾,将其下一节点指向右子树链表头
                preNode -> right = curNode -> right;

                //curNode是当前链表头,下一节点指向左子树链表头
                curNode -> right = curNode -> left;

                curNode -> left = NULL; // 将左子树指向空
            }

            // 链表指针向后移动,模拟递归前序遍历
            curNode = curNode -> right;
        }
    }
};
posted @ 2018-02-06 22:02  言何午  阅读(108)  评论(0编辑  收藏  举报