程序员面试金典--面试22之寻找二叉树中指定结点的下一个结点

题目描述

请设计一个算法,寻找二叉树中指定结点的下一个结点(即中序遍历的后继)。

给定树的根结点指针TreeNode* root和结点的值int p,请返回值为p的结点的后继结点的值。保证结点的值大于等于零小于等于100000且没有重复值,若不存在后继返回-1。


方式一:中序遍历树,将树中节点的值保存到vector中,再遍历一遍vector,找到指定的值的下一个。


树的定义:

struct TreeNode
{
	int val;
	struct TreeNode *left;
	struct TreeNode *right;
	TreeNode(int x):val(x),left(NULL),right(NULL)
	{

	}
};


方式一:

void InOrder(TreeNode *root,vector<int> & v)
{
	if(root == NULL)
		return ;

	InOrder(root->left,v);
	
	v.push_back(root->val);

	InOrder(root->right,v);
}


int FindSucc(TreeNode *root,int p)
{
	if(root == NULL || p < 0)
		return -1;

	vector<int>v ; //因为题目中说没有重复的值,所以想到用vector保存所有的值

	InOrder(root,v);

	for(int i = 0; i < v.size()-1; ++i) //如果是最后一个节点,没有后继。
	{
		if(v[i] == p)
			return v[i+1];
	}
	return -1;
}
方式二:

      要寻找中序遍历的某个节点的下一个节点,肯定是要通过中序遍历实现的,题目中明确告诉我们节点的值没有重复,所以只要在中序遍历的过程中,某个节点的值等于p,则告诉递归者下一个要遍历的节点便是我们要找的节点,这个需要有个信号在多次递归之间进行传递消息,c++里用引用完全可以实现,只需要传递一个整型或bool类型的引用便可。


int InOrder(TreeNode *root,int p,int &sign)
{
	if(root == NULL)
		return -1;

	//遍历左子树。
	int left = InOrder(root->left,p,sign);
	if(left != -1)      //不等于-1,表示查找到了,这里一定要有if,这里是查找
		return left;    //查找是左子树查不到,就去右子树查找,当左子树查找到了,没有必要再去右子树了,直接return .查不到一定还要记得去右子树查找。

	//跟
	if(sign == 1) //这两句话有顺序,别乱写
		return root->val;
	if(root->val == p)
		sign = 1;

	//右子树
	
	return InOrder(root->left,p,sign); //查找右子树是最后一步,这里就没有必要if判断了。直接就可以返回,找到了返回后继节点,找不到返回-1.
}

int FindSucc(TreeNode *root,int p)
{
	if(root == NULL || p < 0)
		return -1;

	int sign = 0;

	return InOrder(root,p,sign);

}


测试代码:
void test()
{
	TreeNode *p1 = new TreeNode(3);
	TreeNode *p2 = new TreeNode(5);
	TreeNode *p3 = new TreeNode(4);
	TreeNode *p4 = new TreeNode(2);
	TreeNode *p5 = new TreeNode(1);
	TreeNode *p6 = new TreeNode(8);

	p1->left = p2;
	p1->right = p3;
	p2->left = p4;
	p2->right = p5;
	p3->right = p6;

	int val = FindSucc(p1,5);
	cout << "val = " << val <<endl;
}

int main()
{
	test();

	cout << "hello..."<<endl;
	
	return 0;
}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值