二叉查找树查找指定排名元素的算法

问题如下:1.查找在二叉查找树中按大小排名为k的节点(如果元素x排名为k,则有k个元素排在x的前面,排名以0为起点),以升序排序

                     2.给出指定键值,返回其在二叉查找树中的排名,升序排序

第1个问题分析:1.任意节点的左子树中的所有节点一定排在自身前面

     2.如果左子树中节点不足,比如查找排名为6的节点,但左子树中只有3个节点,则在右子树中查找排名为k-左子树节点数-1(根)的节点

                     3.如果左子树的大小=k,则返回当前节点

因为需要频繁计算左子树的大小,所以我们使用一个名为size的函数来单独计算,size使用递归实现,但如果树极不平衡或树极大时栈的数量将不可接受,那时可在树节点中加入一个元素来记录每一个节点下的子树大小:

代码如下:

typedef TreeNode * Tree;
typedef TreeNode * TreePosition;
size_t size(Tree T)
{
	if (T == NULL)
		return 0;
	if (T->Left || T->Right)
	{
		if (T->Left == NULL)
			return size(T->Right) + 1;
		if (T->Right == NULL)
			return size(T->Left) + 1;
		else
			return size(T->Left) + size(T->Right) + 1;
	}
	else
		return 1;
}
TreePosition Select(size_t X,Tree T)
{
	size_t iTemp = size(T->Left);
	if (T == NULL)
		return NULL;
	else if (iTemp>X)
		//当左子树的节点数大于排名时,在左子树里递归查找
		return Select(X, T->Left);
	else if (iTemp<X)
		//当左子树节点树不够时,在右子树里递归查找,需要将排名减去左子树的节点数
		//因为此时左子树所有节点都排在前面
		return Select(X - iTemp -1, T->Right);
	//当排名==左子树节点时,返回当前节点
	else if (X == iTemp)
		return T;
}

第2个问题与第一个问题思路基本相同:1.如果当前节点键值大于x,则返回 左子树大小+递归调用右子树的结果+1

                                                                       2如果当前节点键值小于x,则返回递归调用左子树的结果

       3 如果当前节点简直等于x,返回左子树大小

代码如下:.

size_t Rank(ElementType X, Tree T)
{
	size_t iTemp = size(T->Left);
	if (X == T->Element)
		//当键值相等时,返回当前节点的左子树节点数
		return iTemp;
	else if (X > T->Element)
		//当X大于当前键值时,排名=左子树节点数+在右子树里的排名+1(当前节点)
		return iTemp + Rank(X, T->Right) +1;
	else if (X < T->Element)
		return Rank(X,T->Left);
}
    原文作者:查找算法
    原文地址: https://blog.csdn.net/pililipalalar/article/details/51985200
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞