求二叉查找树指定节点后继

题目

设计一个算法,找出二叉查找树中指定节点的“下一个节点”(也就是中序后继)。可以假定每个节点都含有指向父节点的链接。

分析

既然是二叉查找树,我们知道中序遍历结果为递增有序,那么可以直接得到中序遍历结果,在线性查找指定节点的后继。 上述方法是普通解法,但是我们看到题目说每个节点有父节点指针,那么我们可以换一个思路: (1)假设该节点有右子树,那么根据中序遍历的步骤,下一个访问节点即是其右子树的最左节点; (2)假设该节点没有右子树,其在父节点的左子树上,那么下一个访问节点即是其父节点; (3)假设该节点没有右子树,且其在父节点的右子树上,这怎么办呢?我们依次根据其父节点指针上溯,直到找到一个祖先节点,使得该节点位于此祖先节点的左子树。 其中,后两种情况可以合二为一处理。

代码

	/*方法一,得到中序遍历序列*/
	int findSucc(TreeNode* root, int p) {
		// write code here
		vector<int> inOrderVals;
		inOrder(inOrderVals, root);
		auto iter = find(inOrderVals.begin(), inOrderVals.end(), p);
		if (++iter != inOrderVals.end())
			return *iter;
		return -1;
	}

	/*中序遍历二叉树*/
	void inOrder(vector<int> &vals, TreeNode *root)
	{
		if (!root)
			return;
		inOrder(vals, root->left);
		vals.push_back(root->val);
		inOrder(vals, root->right);
	}
/*方法二:假设该树每个节点含有指向父节点的链接*/
	TreeNode* FindSucc2(TreeNode *root, TreeNode *node)
	{
		if (root == NULL || node == NULL)
			return NULL;

		/*如果该节点有右子树,则右子树的最左边节点即为后继*/
		if (node->right != NULL)
		{
			TreeNode *ret = node->right;
			while (ret->left != NULL)
				ret = ret->left;
			return ret;
		}
		else {
			/*若该节点无右子树,上溯遍历,找到第一个祖先节点使得该节点位于其左子树*/
			TreeNode *p = node->parent;
			while (p != NULL && node == p->right)
			{
				node = p;
				p = p->parent;
			}
			return node;
		}
	}
    原文作者:二叉查找树
    原文地址: https://blog.csdn.net/fly_yr/article/details/52174018
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞