二叉查找树的查找和插入和删除操作

二叉搜索树也称二叉排序树或二叉查找树;

二叉搜索树:一颗二叉树可以为空;如果不为空,满足以下性质:

1.非空左子树的所有键值小于其根结点的键值。

2.非空右子树的所有键值大于其根节点的键值。

3.左、右子树都是二叉搜索树。

 

查找:Find

1.若X小于根节点键值,只需在左子树中继续搜索

2.若X大于根节点键值,只需在右子树中继续搜索

3.若两者比较结果是相等,返回指向此结点的指针

尾递归

Position Find (ElementType X, BinTree BST) {

  if (!BST)  return NULL;  //查找失败

  if (X > BST->Data)  

    return Find (X, BST->Right);  //在右子树中继续查找

  else if (X < BST->Data)

    return Find (X, BST->Left);  //在左子树中继续查找

  else //X==BST->Data

    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;  //查找失败

}

查找的效率取决于树的高度

 

查找最大和最小元素

最大元素一定是在树的最右分枝的端结点上,最小元素一定是在树的最左分枝的端结点上

1.查找最小元素的递归函数

Position FindMin (BinTree BST) {

  if (!BST)   return NULL;  //空的二叉搜索树,返回NULL

  else if (!BST->Left)

    return BST;  //找到最左叶结点并返回

  else

    return FindMin (BST->Left)  //沿左分枝继续查找

}

 

2.查找最大元素的迭代函数

Position FindMax (BinTree BST) {

  if (BST) {

    while (BST->Right) {

      BST = BST->Right;  

      //沿右分枝继续查找,直到最右叶结点

    }

  }

  return BST;

}

 

插入

BinTree Insert (ElementType X, BinTree BST) {

  if (!BST) {

    //若原树为空,生成并返回一个结点的二叉搜索树

    BST = malloc (sizeof(struct 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);

  }

  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;

}

 

posted @ 2020-04-07 22:53  郑NINE  阅读(609)  评论(0编辑  收藏  举报