二叉搜索树

二叉树搜索树

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

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

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

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

 

查找:1.查找关键之2.查找最值

对于遇到的每个结点x,都会比较x.key与k的大小,如果相等,就终止查找,否则,决定是继续往左子树还是右子树查找。因此,整个查找过程就是从根节点开始一直向下的一条路径,若假设树的高度是h,那么查找过程的时间复杂度就是O(h)。

递归做法:

  Pision Find(elementType x,Pision 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 //找到 
          return bst;
  }

此递归为尾递归,递归效率并不高,一般尾递归都可以用循环表示:

  Pision Find(elementType x,Pision binTree bst) 
  {
      while(bst)
      {
          if(x>bst->data)//去右子树中查找 
              bst=bst->right);
          else if(x<bst->data)//去左子树中查找 
              bst=x,bst->Left;
          else //找到 
          return bst;
      }
      return NULL;
  }

最大元素一定是在树的最右分支的端结点上(一定没有右儿子)

最小元素一定是在树的最左分支的端结点上(一定没有左儿子)

递归做法:

  Pision FindMin(binTree bst) 
  {
      if(!bst)
          return NULL
      else if(!bst->Left)
          return bst->Left
      else FindMin(bst);
      return bst;
  }
  Pision FindMax(binTree bst) 
  {
      if(!bst)
          return NULL
      else if(!bst->Right)
          return bst->Right
      else FindMax(bst);
      return bst;
  }

迭代做法:

  Pision FindMin(binTree bst) 
  {
      if(bst)
      {
          while(bst->Left)
          bst=bst->Left;
      }
      return bst;
  }
  Pision FindMax(binTree bst) 
  {
      if(bst)
      {
          while(bst->Right)
          bst=bst->Right;
      }
      return bst;
  }

插入

(关键是找到应该插入的位置)

BST的插入过程非常简单,很类似与二叉树搜索树的查找过程。当需要插入一个新结点时,从根节点开始,迭代或者递归向下移动,直到遇到一个空的指针NILL,需要插入的值即被存储在该结点位置。

递归做法:

binTree insert( elemenType x,binTree bst) 
{
    if(!bst)
    {
        bst=(binTree)malloc(sizeof(treeNode));
        bst->data=x;
        bst->Left=bst->Right=NULL;
    }
    else
    {
        if(x<bst->data)
        {
            bst->Left=insert(x,bst->Left);
        }
        else if(x>bst->Right)
        {
            bst->Right=insert(x,bst->Right);
        }
        //如果x已经存在,则什么都不做 
    }
    return bst;
}

迭代做法:

void insert( elemenType x,binTree bst) 
{
    binTree p=(binTree)malloc(sizeof(treeNode));
    binTree temp=NULL;
    p->data=x;
    p->Left=p->Right=NULL;
    if(!bst)
    {
        bst=p;
        return ;
    }
    while(bst)
    {
        temp=bst;
        if(x>bst->data)
            bst=bst->Right
        else if(x<bst->data)
            bst=bst->Left;
        else
            return ; 
    }
    if(p->data>temp->data)
        temp->Right=p;
    else if(p->data<temp->data)
        temp->Left=p;
}

删除

二叉搜索树的结点删除比插入较为复杂,总体来说,结点的删除可归结为三种情况:

因为左子树的最大值和右子树的最小值一定不会有两个结点

递归方法:

binTree Delete(elementype x,binsTree bst)
{
    binTree temp;
    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)//该删除的结点有左右孩子 
        {
            temp=FindMin(bst->Right);//去右子树中找最小值代替该删除结点 
            bst->data=temp->data;
            bst->Right=Delete(bst->data,bst->Right);//在右子树中删除最小值 
        }
        else
        {
            if(!bst->Left&&!bst->Left)//无孩子结点 
            {
                free(bst);
                return NULL;
            }
            temp=bst;
            if(!bst->Left)//无左子树 
                bst=bst->Right;
            else(!bst->Right)//无右子树 
                bst=bst->Left;
            free(temp);
        }
    }
    return bst;
}     

 二插搜索树的调整:

未完

原文地址:https://www.cnblogs.com/TX980502/p/8254392.html