问题描述
最后再扩展了一下中序遍历的扁平化版本。
笔记
看了半天还是比较能接受递归的解法。参考:
[LeetCode] flatten binary tree 扁平化二叉树
思路:假设以下函数
TreeNode covert2link(TreeNode *root)
可以将一棵树转化为符合要求的链表,并返回链表的尾部(链表的头部必定是root)。那么该怎么做呢?那就是:
- 首先,调用这个函数把左子树转化为符合要求的链表,得到左子树转化成的链表的尾部。
- 再调用这个函数把右子树转化成符合要求的链表,得到右子树转化成的链表的尾部。
- 然后按照前序遍历的定义,将《root》–《左子树链表》–《右子树链表》按序连接起来。
- 最后返回整个整合好的链表的尾部。
代码
笔记里的递归的解法似乎比较好懂一点
/**
* Definition of TreeNode:
* class TreeNode {
* public:
* int val;
* TreeNode *left, *right;
* TreeNode(int val) {
* this->val = val;
* this->left = this->right = NULL;
* }
* }
*/
class Solution {
public:
/**
* @param root: a TreeNode, the root of the binary tree
* @return: nothing
*/
void flatten(TreeNode *root) {
// write your code here
convert2link(root);
}
TreeNode* convert2link(TreeNode* root)
{
if (root == NULL)
return NULL;
// 首先,调用这个函数把左子树转化为符合要求的链表,得到左子树转化成的链表的尾部。
TreeNode* leftLinkTail = convert2link(root->left);
// 再调用这个函数把右子树转化成符合要求的链表,得到右子树转化成的链表的尾部。
TreeNode* rightLinkTail = convert2link(root->right);
// 然后按照前序遍历的定义,将《root》–《左子树链表》–《右子树链表》按序连接起来。
if (leftLinkTail)
{
leftLinkTail->right = root->right;// 《左子树链表》–《右子树链表》
root->right = root->left;// 《root》–《左子树链表》
}
root->left = NULL;
// 最后返回整个整合好的链表的尾部
if (rightLinkTail)
return rightLinkTail;
else if (leftLinkTail)
return leftLinkTail;
else
return root;
}
};
九章算法的非递归解法没有看懂
class Solution {
public:
/**
* @param root: a TreeNode, the root of the binary tree
* @return: nothing
*/
void flatten(TreeNode *root) {
// write your code here
if (root == NULL) return;
while (root) {
if (root->left) {
TreeNode *pre = root->left;
while (pre->right)
pre = pre->right;
pre->right = root->right;
root->right = root->left;
root->left = NULL;
}
root = root->right;
}
}
};
最后扩展一下,如果要求flatten成中序遍历的顺序,该怎么做呢?我写了一个版本,感觉有点滥用了pair了,而且不知道是否正确,请高手指导指导,谢谢。
//
// main.cpp
// inorderBtree2Link
//
// Created by SteveWong on 7/20/16.
// Copyright © 2016 SteveWong. All rights reserved.
//
#include <iostream>
using namespace std;
class TreeNode
{
public:
int val;
TreeNode *left, *right;
TreeNode(int val)
{
this->val = val;
this->left = this->right = NULL;
}
};
void inorder(TreeNode *root)
{
if (root == NULL)
{
return;
}
if (root->left)
{
cout << root->val << " ->l " << root->left->val << endl;
}
if (root->right)
{
cout << root->val << " ->r " << root->right->val << endl;
}
inorder(root->left);
// cout << root->val << ' ';
inorder(root->right);
}
pair<TreeNode*, TreeNode*> convert2linkInorder(TreeNode *root)
{
if (root == NULL)
{
return pair<TreeNode*, TreeNode*>(NULL, NULL);
}
pair<TreeNode*, TreeNode*> tpleft = convert2linkInorder(root->left);
pair<TreeNode*, TreeNode*> tpright = convert2linkInorder(root->right);
TreeNode* head = NULL;
TreeNode* tail = NULL;
if (tpleft.first && tpleft.second)// 有左子树
{
tpleft.second->right = root;
tpleft.second->left = NULL;
head = tpleft.first;
}
else //无左子树
{
head = root;
}
root->left = NULL;
if (tpright.first && tpright.second)// 有右子树
{
root->right = tpright.first;
tail = tpright.second;
}
else// 无右子树
{
tail = root;
}
return pair<TreeNode*, TreeNode*>(head, tail);
}
int main(int argc, const char * argv[]) {
// insert code here...
// std::cout << "Hello, World!\n";
TreeNode *root = new TreeNode(0);
TreeNode *left = new TreeNode(1);
TreeNode *right = new TreeNode(2);
root->left = left;
root->right = right;
left->left = new TreeNode(3);
left->right = new TreeNode(4);
right->left = new TreeNode(5);
right->right = new TreeNode(6);
inorder(root);
auto res = convert2linkInorder(root);
cout << "inorder" << endl;
inorder(res.first);
return 0;
}