zoukankan      html  css  js  c++  java
  • 二叉搜索树

    二叉树搜索树

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

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

     二插搜索树的调整:

    未完

  • 相关阅读:
    android中使用百度定位sdk实时的计算移动距离
    Android NDK开发常见错误
    cocos2dx中使用iconv转码(win32,iOS,Android)
    史上最全的CSS hack方式一览
    谈谈SQL 语句的优化技术
    PIVOT 和 UPIVOT 的使用(行转列)
    JQuery的Ajax跨域请求的解决方案
    64位windows2003 未在本地计算机上注册 microsoft.jet.oledb.4.0 提供程序
    httpModules 与 httpHandlers
    删除事件查看器中多余的日志分类
  • 原文地址:https://www.cnblogs.com/TX980502/p/8254392.html
Copyright © 2011-2022 走看看