数据结构 浙大MOOC--树(中)

在这里插入图片描述

二叉搜索树的查找操作

查找从根节点开始,如果树为空,返回NULL,
如果搜索树非空,则根节点关键字和X进行比较,并进行不同处理:

  1. 如果x小于根节点键值,只需在左子树中继续搜索
  2. 如果x大于根节点的键值,在右子树中进行继续搜索
  3. 若两者比较结果是相等,搜索完成,返回指向此节点的指针
//二叉搜索树的查找操作
//递归实现
Position Find(ElementType X, BinTree BST)
{
	if(!BST)	//BST为空
	{
		return NULL;
	}
	if(X > BST->Data)
	{
		return Find(X, BST->Right);	//则在右子树中继续查找
	}
	else if(X < BST->Data)
	{
		return Find(X, BST->Left);	//在左子树中继续查找
	}
	else
	{
		return BST;		//查找成功,返回节点的找到节点的地址
	}
}

由于非递归函数的效率更高,于是可以将"尾递归"改为迭代函数
查找的效率取决于树的高度

Position IterFind(ElementType X, BinTree BST)
{
	while(BST)
	{
		if(X > BST->Data)
		{
			BST = BST->Right;	//向右子树中移动,继续查找
		}
		else if (X < BST->Data)
		{
			BST = BST->Left;	//向左子树中移动,继续查找
		}
		else
		{
			return BST;		//查找成功,返回节点的找到节点的地址
		}
	}
	return NULL;	//查找失败
}

注意

最大元素一定是在树的最有分支的端节点上
最小元素一定是在树的最左分支的端节点上
此处的最左和最右是指物理意义上的相对位置

//查找最小元素的递归函数
Position FindMin(BinTree BST)
{
	if(!BST)
	{
		return NULL;	//空的二叉搜索树,返回NULL
	}
	else if (!BST->Left)	//当前节点的左子树为空,则此时已经递归到了最左端
	{
		return BST;	//找到最左叶节点并返回
	}
	else
	{
		return FindMin(BST->Left);	//递归搜索左子树,沿左分支继续查找
	}
}
//查找最小元素的迭代函数
Position FindMin(BinTree BST)
{
	if(BST != NULL)
	{
		while(BST->Left != NULL)
		{
			BST = BST->Left;
		}
	}
	return BST;
}
//查找最大元素的递归函数
Position FindMax(BinTree BST)
{
	if(BST == NULL)
	{
		return NULL;
	}
	else if(BST->Right == NULL)
	{
		return BST;	//找到最右节点并返回
	}
	else 
	{
		return FindMax(BST->Right);
	}
}

//查找最大元素的迭代函数
Position FindMax(BinTree BST)
{
	if(BST)		//BST不为空
	{
		while(BST->Right)	//沿右分支继续查找,直到最右叶节点
		{
			BST = BST->Right;
		}
	}
	return BST;	
}

二叉搜索树的插入

关键是要找到元素应该插入的位置,可以采用与Find类似的方法
递归实现

//二叉搜索树的插入算法
//BST始终是该树的根节点,
BinTree Insert(ElementType X, BinTree BST)
{
	if(!BST)	//若原树为空,生成并返回一个节点的二叉搜索树
	{
		BST = malloc(sizeof(stuct TreeNode));
		BST->Data = X;
		BST->Left = BST->Right = NULL;		//左右节点指针均置为空
	}
	else	//开始找要插入元素的位置
	{
		if(X < BST->Data)
		{
			BST->Left = Insert(X, BST->Left);	//递归插入左子树
		}
		else if(X > BST->Data)
		{
			BST->Right = Insert(X, BST->Right);	//递归插入右子树
		}
		//else X已经存在,什么都不做
	}
	return BST;
}

二叉搜索树的删除

  1. 要删除的是叶节点,直接删除,并修改其父节点指针–置为NULL
  2. 要删除的节点只有一个孩子节点:将其父节点的指针指向要删除节点的孩子节点
  3. 要删除的节点有左右两棵子树:用另一节点代替删除节点:右子树的最小元素或者左子树的最大元素
BinTree Delete (ElementType X, BinTree BST)
{
	Position Tmp;
	if(!BST)
	{
		printf("要删除的元素未找到");
	}
	else if(X < BST->Data)
	{
		BST->Left = Delete(X, BST->Left);	//左子树递归删除
	}
	else if(X > BST->Data)
	{
		BST->Right = Delete(X, BST->Right);	//右子树递归删除
	}
	else	//找到要删除的节点
	{
		if(BST->Left && BST->Right)		//被删除节点的左右两个子节点
		{
			Tmp = FindMin(BST->Right);	//在右子树中招最小的元素填充删除节点
			BST->Data = Tmp->Data;
			BST->Right = Delete(BST->Data, BST->Right);	//在删除节点的右子树中删除最小元素
		}
		else
		{
			Tmp = BST;
			if(!BST->Left)	//有右孩子或无子节点
			{
				BST = BST->Right;
			}
			else if(!BST->Right)	//有左孩子或无子节点
			{
				BST = BST->Left;
			}
			free(tmp);
		}

	}
	return BST;
}

平衡二叉树

在这里插入图片描述

结论:给定节点数为n的AVL树的最大高度为O(logn)

平衡二叉树的调整

猜你喜欢

转载自blog.csdn.net/HdUIprince/article/details/83118191