例如数组 a[]={5,7,6,9,11,10,8}
判断是否是二查搜索树后序遍历,则只需要将该序列还原为搜索二叉树,即可,但是二叉树的还原过程
1.确定根节点所在,当然因为是后续所以根节点在数组的末尾元素
2.确定两棵子树的范围以及依次插入的方向
在此题中8 为根节点所在 6 和10 是距离根节点最近的元素,也即插入方向是从6 和10 开始顺次向前,6到5的位置截止,10到9的位置截止
int a[]={5,7,6,9,11,10,8};
//判断序列是否是二叉搜索树的后序遍历
struct Node{
int val;
Node* left;
Node* right;
Node():val(0),left(NULL),right(NULL)
{}
};
int* FindSplit(int* const a,int length,int value)
{
if(NULL==a)
return NULL;
//从数组a中找到以value为分界的地方
int key=value;
for(int i=0;i=value)
{
return &a[i];
}
}
return NULL;
}
void InsertNode(Node* root,int value)
{
if(NULL==root)
{
root=new Node();
root->val=value;
return;
}
Node* cur=root;
while(NULL!=cur)
{
if(cur->val>value)
{
//左子树
if(NULL==cur->left)
{
cur->left=new Node();
cur->left->val=value;
break;
}
else
{
cur=cur->left;
}
}
else
{
//右子树
if(NULL==cur->right)
{
cur->right=new Node();
cur->right->val=value;
break;
}
else
{
cur=cur->right;
}
}
}
}
void ReverTraversal(Node* root,vector &mm)
{
if(NULL==root)
{
return ;
}
ReverTraversal(root->left,mm);
ReverTraversal(root->right,mm);
mm.push_back(root->val);
}
int main()
{
int* begin=NULL,*end=NULL,* mid=NULL;
begin=a;
end=begin+(sizeof(a)/sizeof(int)-1);
mid=FindSplit(a,sizeof(a)/sizeof(int),*end);
Node* root=new Node();
root->val=*end;
int nCount=0;
int* prev=mid-1,*reser=(end-1);
for(;prev!=begin&&reser!=mid;)
{
if(nCount&0x1)
{
InsertNode(root,*prev);
prev--;
nCount++;
}
else
{
InsertNode(root,*reser);
reser--;
nCount++;
}
}
while(prev!=begin)
{
InsertNode(root,*prev);
prev--;
}
while(reser!=mid)
{
InsertNode(root,*reser);
reser--;
}
InsertNode(root,*begin);
InsertNode(root,*mid);
//进行检测
vectorhe;
ReverTraversal(root,he);
if(he.size()==sizeof(a)/sizeof(int))
{
bool mark=false;
for(nCount=0;nCount!=he.size();nCount++)
{
if(he[nCount]!=a[nCount])
{
cout<<"不是二查搜索树的后续遍历序列\n";
mark=true;
break;
}
}
if(!mark)
{
cout<<"是二查搜索树的后续遍历序列\n";
}
}
else
{
cout<<"不是二查搜索树的后续遍历序列\n";
}
return 0;
}