二叉搜索樹

二叉樹搜索樹spa

二叉搜索樹:一顆二叉樹能夠爲空:若是不爲空,知足如下性質:3d

1.非空左子樹的全部值小於根節點的鍵值指針

2.非空右子樹的全部值大於根節點的鍵值code

3.左右子樹都是二叉搜索樹blog

 

 

查找:1.查找關鍵之2.查找最值遞歸

對於遇到的每一個結點x,都會比較x.key與k的大小,若是相等,就終止查找,不然,決定是繼續往左子樹仍是右子樹查找。所以,整個查找過程就是從根節點開始一直向下的一條路徑,若假設樹的高度是h,那麼查找過程的時間複雜度就是O(h)。element

遞歸作法:io

  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;
  }

此遞歸爲尾遞歸,遞歸效率並不高,通常尾遞歸均可以用循環表示:class

  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;
}     

 二插搜索樹的調整:

未完

相關文章
相關標籤/搜索