笛卡尔树是一种特定的二叉树数据结构,可由数列构造,在范围最值查询、范围top k查询(range top k queries)等问题上有广泛应用。它具有堆的有序性,中序遍历可以输出原数列。 //引自百度百科
关于笛卡尔树的构造,可参考:
https://www.cnblogs.com/CaptainSlow/p/9282507.html
https://github.com/sighingnow/sighingnow.github.io/blob/master/_posts/algorithm/2015-02-12-rmq_lca_cartesian_tree.md (有构造的图解,易于理解)
动态构造版本:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<stack>
using namespace std;
int a[105],n;
struct Node
{
int key,val;
Node *parent,*left,*right;
Node(int key=0,int val=0, Node *l=NULL, Node *r=NULL, Node *p=NULL) { this->key=key; this->val=val;
this->left=l; this->right=r; this->parent=p; };
}*root;
Node *build() //根节点为最小值,即最小顶
{
stack<Node *> st;
Node *rt,*last;
for(int i=1;i<=n;++i)
{
Node *temp=new Node(i,a[i]); last=NULL;
while(!st.empty())
{
if(st.top()->val<temp->val) //最小顶为 < ,最大顶为 >
{
rt=st.top();
if(rt->right)
{
rt->right->parent=temp;
temp->left=rt->right;
}
rt->right=temp;
temp->parent=rt;
break; //可以结束了
}
last=st.top(); st.pop();
}
if(st.empty()&&last)
{
last->parent=temp;
temp->left=last;
}
st.push(temp);
}
while(!st.empty()) rt=st.top(), st.pop(); //取根节点
return rt;
}
void in_order(Node *node)
{
if(node==NULL) return;
in_order(node->left);
printf("%d\n",node->val);
in_order(node->right);
}
void delet(Node *node)
{
if(node==NULL) return;
delet(node->left);
delet(node->right);
delete node;
}
void destroy(Node *node)
{
delet(node);
root=NULL;
}
int main()
{
while(~scanf("%d",&n))
{
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
root=build();
in_order(root);
destroy(root);
if(!root) cout<<"YES\n";
}
}
静态构造模板:
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<stack>
using namespace std;
int a[105],n;
int fa[105],ls[105],rs[105];
int build()
{
stack<int> st; //存放节点的key值
int rt,last;
for(int i=1;i<=n;++i)
{
last=0;
while(!st.empty())
{
if(a[st.top()]<a[i])
{
rt=st.top();
if(rs[rt])
{
fa[rs[rt]]=i;
ls[i]=rs[rt];
}
rs[rt]=i;
fa[i]=rt;
break;
}
last=st.top(); st.pop();
}
if(st.empty()&&last)
{
fa[last]=i;
ls[i]=last;
}
st.push(i);
}
while(!st.empty()) rt=st.top(), st.pop();
return rt;
}
void print(stack<int> S)
{
while(!S.empty())
{
cout<<S.top()<<' ';S.pop();
}cout<<endl;
}
void in_order(int node)
{
if(!node) return;
in_order(ls[node]);
printf("%d\n",a[node]);
in_order(rs[node]);
}
/*void in_order(int node) //非递归版本,尚未写成
{
stack<int> st;
bool vis[105]={0};
st.push(node);
while(!st.empty())
{
while(ls[node]&&!vis[ls[node]])
{
node=ls[node];
st.push(node);
}print(st);
st.pop(); vis[node]=1;
printf("%d\n",a[node]);
if(rs[node])
{
node=rs[node];
st.push(node);
}
else
{
print(st);
while(!rs[node]&&!vis[fa[node]])
{//cout<<node<<' ';
node=fa[node];
printf("%d\n",a[node]);
vis[node]=1;
st.pop();print(st);
}//cout<<node<<endl;
cout<<endl;print(st);
if(rs[node]&&!vis[rs[node]])
{
node=rs[node];
st.push(node);
}print(st);
}
}
}*/
void init()
{
memset(ls,0,sizeof(ls));
memset(rs,0,sizeof(rs));
memset(fa,0,sizeof(fa));
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d",&a[i]);
init();
int root=build();
in_order(root);
return 0;
}