给你n个值,由输入顺序按照二叉排序树(bst)的方法构造树,构造完毕后问:除了根节点以外每个节点的父节点是值为多少?
分析:
由于n的取值较大,在极端情况下直接构造BST的复杂度为O(n^2),不可取。
参考了题解http://www.cnblogs.com/helenawang/p/5501857.html,里面解释的非常好。
由于BST存在极端不平衡情况可能超时,插入过程中需对BST进行维护,构造成AVL可以保证复杂度为O(nlogn)。
在看题解的时候数据结构学的具体构造与旋转已经忘的差不多了,看代码发现并不需要构造出AVL,利用set的lower_bound可以很简单的实现平衡性。
通过分析一个待插入节点v的大于v的第一个元素与小于v的第一个元素之间关系,可以找到具体插入方法。具体可以参考题解。
代码十分优美:
#include <algorithm>
#include <iostream>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <string>
#include <fstream>
#include <vector>
#include <cstdio>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
using namespace std;
#define INF 0x3f3f3f3f
const int N=100005;
const int mod=1e9+7;
int a[N];
struct Node {
int d;
int lc,rc;
Node(){}
Node(int d):d(d),lc(-1),rc(-1){}
}nodes[N];
int main() {
int n;
while (cin>>n) {
for (int i=0; i<n; i++) {
scanf("%d",&a[i]);
}
set<int> s;
map<int, int> left;
map<int, int> right;
int res;
s.insert(a[0]);
for (int i=1; i<n; i++) {
set<int>::iterator pos=s.lower_bound(a[i]);
if (pos!=s.end()&&left.count(*pos)==0) {
res=*pos;
left[res]=a[i];
} else {
pos--;
res=*pos;
right[res]=a[i];
}
printf("%d ",res);
s.insert(a[i]);
}
cout<<endl;
}
return 0;
}

本文介绍了一种高效方法来构建二叉搜索树,并详细解释了如何通过遍历过程找到每个非根节点的父节点。利用C++中的set数据结构,通过lower_bound函数简化了插入操作,确保了树的平衡性,从而有效避免了极端情况下的性能瓶颈。



492

被折叠的 条评论
为什么被折叠?



