給你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;
}