相关问题:已知二叉树的前序遍历序列和中序遍历序列,要求重新恢复该二叉树。
给你一个二叉搜索树的前序遍历序列,恢复此二叉搜索树
文章末尾给出了一个复杂度是O(n)的算法。复杂度是O(n^2)的代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <vector>
using namespace std;
struct Node
{
int key; Node* left; Node* right;
Node(int k, Node* l, Node* r): key(k), left(l), right(r){};
};
Node* construct(vector<int> pre)
{
if(pre.size())
{
int data = pre[0];
vector<int> pre_l, pre_r;
if(pre.size()>1)
for(int i=1; i<pre.size(); i++)
if(pre[i]<pre[0])
pre_l.push_back(pre[i]);
else
pre_r.push_back(pre[i]);
Node* root = new Node(data, NULL, NULL);
root->left = construct(pre_l);
root->right = construct(pre_r);
return root;
}
else
return NULL;
}
void print(Node* root){
if(root){
print(root->left); printf("%d|", root->key);
print(root->right);
}
}
int main()
{
int pre[] = {10, 5, 1, 7, 40, 50};
vector<int> pre_vec = vector<int>(pre, pre+6);
Node* root = construct(pre_vec);
print(root);
}
复杂度是O(n)的算法。思路:
The trick is to set a range {min.. max} for every node. Initialize the range as {INT_MIN .. INT_MAX}.The first node will definitely be in range, so create root node. Toconstruct the left subtree, set the range as {INT_MIN …root->data}.If a values is in the range {INT_MIN .. root->data}, the values ispart part of left subtree. To construct the right subtree, set therange as {root->data..max .. INT_MAX}.
以下是网上某人的代码。我看不明白为何constructTreeUtil 的参数列表里 int key 的作用。
// A recursive function to construct BST from pre[]. preIndex is used
// to keep track of index in pre[].
Node* constructTreeUtil( int pre[], int* preIndex, int key,
int min, int max, int size ){
// Base case
if( *preIndex >= size )
return NULL;
Node* root = NULL;
// If current element of pre[] is in range, then
// only it is part of current subtree
if( key > min && key < max ) {
root = new Node (key, NULL, NULL );
*preIndex = *preIndex + 1;
if (*preIndex < size) {
root->left = constructTreeUtil( pre, preIndex, pre[*preIndex],
min, key, size );
root->right = constructTreeUtil( pre, preIndex, pre[*preIndex],
key, max, size );
}
}
return root;
}
// The function to construct BST from given preorder traversal.
Node *constructTree (int pre[], int size)
{
int preIndex = 0;
return constructTreeUtil ( pre, &preIndex, pre[0], INT_MIN, INT_MAX, size );
}
int main()
{
int pre[] = {10, 5, 1, 7, 40, 50};
Node* root = constructTree(pre, 6);
print(root);
}
我把constructTreeUtil 的参数 int key 去掉之后,新的代码代码如下(以下代码经过测试):
#include<stdio.h>
#include<stdlib.h>
#include <iostream>
struct Node
{
int key; Node* left; Node* right;
Node(int k, Node* l, Node* r): key(k), left(l), right(r){};
};
// A recursive function to construct BST from pre[]. preIndex is used
// to keep track of index in pre[].
Node* constructTreeUtil( int pre[], int* preIndex,
int min, int max, int size ){
// Base case
if( *preIndex >= size )
return NULL;
Node* root = NULL;
int key = pre[*preIndex];
// If current element of pre[] is in range, then
// only it is part of current subtree
if( key > min && key < max ) {
root = new Node (key, NULL, NULL );
*preIndex = *preIndex + 1;
if (*preIndex < size) {
root->left = constructTreeUtil( pre, preIndex,
min, key, size );
root->right = constructTreeUtil( pre, preIndex,
key, max, size );
}
}
return root;
}
// The function to construct BST from given preorder traversal.
Node *constructTree (int pre[], int size)
{
int preIndex = 0;
return constructTreeUtil ( pre, &preIndex, INT_MIN, INT_MAX, size );
}
void print(Node* root){
if(root){
print(root->left); printf("%d|", root->key);
print(root->right);
}
}
int main()
{
int pre[] = {10, 8, 7, 6, 9, 100, 20, 30, 40, 35, 110};
Node* root = constructTree(pre, 11);
print(root);
int x; std::cin>>x;
}