判断一个数列是否是二叉树后序遍历的结果

例如数组 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<length;i++)
	{
		//找到第一个比value大的位置
		if(a[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<int> &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);
	//进行检测
	vector<int >he;
	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;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

世纪殇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值