Given a binary tree, flatten it to a linked list in-place.
For example,
Given
1
/ \
2 5
/ \ \
3 4 6
The flattened tree should look like: 1
\
2
\
3
\
4
\
5
\
6
問題描述:給定一個二叉樹,將它變成一個類似上面那樣的鏈表,而且操作要原地進行。
根據上面兩個樹的樣子,可以看到,在鏈表形式中,節點的左孩子為空,右孩子為先序遍歷中當前節點的前一個節點。
因此,可以構造這樣一個函數,它將以root為根的樹變成上面這樣類似鏈表的形式,返回整個子樹的先序遍歷的最後一個節點。
那麼,它如何實現這個過程呢?對它的左子樹調用上面的函數,將左邊變成類似鏈表的形式,並且獲得了左子樹中先序遍歷的最後一個節點last_node,接著,將最後一個幾點的
左孩子置空,右孩子置為root->right,然後root->right = root->left,最後,如果root->right不空,則對右子樹調用上面的函數,並返回右子樹的最後一個節點。
在這裡還有一種特殊情況,就是左右子樹都為空,此時,不做任何操作,然後返回該節點本身。
#include
#include
#include
using namespace std;
struct TreeNode {
int val;
TreeNode *left;
TreeNode *right;
TreeNode(int x) : val(x), left(NULL), right(NULL) {}
};
void tree_insert(TreeNode *&root, TreeNode *pnode)
{
if(root == NULL) {
root = pnode;
return;
}
if(pnode->val <= root->val) {
tree_insert(root->left, pnode);
}
else {
tree_insert(root->right, pnode);
}
}
void tree_create(TreeNode *&root, vector::iterator beg, vector::iterator end)
{
TreeNode *pnode = NULL;
while(beg != end) {
pnode = new TreeNode(*beg);
tree_insert(root, pnode);
++beg;
}
}
void tree_traverse(TreeNode *root)
{
if(root != NULL) {
cout << root->val << " ";
tree_traverse(root->left);
tree_traverse(root->right);
}
}
void tree_structure(TreeNode *root)
{
if(root != NULL) {
cout << "root :" << root->val << endl;
if(root->left == NULL) {
cout << "left child is NULL " << endl;
tree_structure(root->right);
}
else
cout << "error!" << endl;
}
}
void tree_destroy(TreeNode *&root)
{
if(root != NULL) {
tree_destroy(root->left);
tree_destroy(root->right);
delete root;
}
}
class Solution {
public:
TreeNode *flatten_child(TreeNode *root)
{
if(root != NULL) {
if(root->left == NULL && root->right == NULL)
return root;
TreeNode *last_node = NULL;
if(root->left == NULL) {
return flatten_child(root->right);
}
last_node = flatten_child(root->left);
if(root->right == NULL) {
root->right = root->left;
root->left = NULL;
return last_node;
}
last_node->right = root->right;
last_node->left = NULL;
root->right = root->left;
root->left = NULL;
return flatten_child(last_node->right);
}
}
void flatten(TreeNode *root)
{
if(root != NULL)
flatten_child(root);
}
};
int main(int argc, char *argv[])
{
int arr[] = {3, 2, 1, 4, 5};
int len = sizeof(arr) / sizeof(arr[0]);
vector vec(arr, arr + len);
TreeNode *tree = NULL;
tree_create(tree, vec.begin(), vec.end());
tree_traverse(tree);
cout << endl;
Solution sol;
sol.flatten(tree);
tree_structure(tree);
tree_destroy(tree);
return 0;
}
為了展示樹的構造和變化,給出了整個程序。首先構造了一個二叉樹,然後對它進行了變換,最後用tree_structure()打印樹的結構情況。
