• 二叉树-二叉查找树-AVL树-遍历


    一、二叉树

    定义:每个节点都不能有多于两个的儿子的树。

    二叉树节点声明:

    1 struct treeNode
    2 {
    3      elementType   element;
    4      treeNode      * left;
    5      treeNode      * right;               
    6 }

    应用:

    中缀表达式——>后缀表达式(栈的应用)——>表达式树(栈的应用2)

    栈的应用2:读取后缀表达式,操作数入栈,遇操作符后,指向栈里前两位元素t1和t2的指针出栈(t1先弹出,作为该操作符的右儿子),并将指向该操作符的指针入栈。

     二、二叉查找树

    定义:

    结构性:二叉树;

    排序性:右子树中最小值  >  X关键字  >  左子树中最大值(对任意节点关键字X均成立)

    1、清空树(递归)makeEmpty

     1 searchTree * makeEmpty( searchTree * T)
     2 {
     3      if( T != NULL)
     4     {
     5          makeEmpty( T -> left);
     6          makeEmpty( T -> right);
     7          delete  (T); // 基准情况
     8     }  
     9      return T;  
    10 }

     2、Find

    searchTree * find( elementType X , searchTree * T)
    {
          if( T = NULL)
             return NULL; //非空判断
    
          if(X < T->element)
             return find (X , T->left);
          else  
          if(X > T->element)
             return find(X , T->right);    
          else
             return T;  //找到元素X
    }    

    3、findMin  &&  findMax(举一例,(非)递归法,利用其排序性找到相应节点)

    递归法:

    searchTree * findMax(  searchTree * T)
    {
          if( T = NULL)
              return NULL; //非空判断
          else    
          if(T->right == NULL)    
             return T;      //基准情况
          else
             return findMax(T->right);
    }  

    非递归法:

    searchTree * findMax(  searchTree * T)
    {
          if( T = NULL)
              return NULL; //非空判断
          else    
          while(T->right != NULL)    
              T = T->right;
    
    return T; }

    4、insert

    searchTree * insert( elementType X , searchTree * T)
    {
          if( T == NULL)
          {
               T = searchTree New(searchTree);
               if(T == NULL)
                  cout << "out of space." << endl; 
               else
                   {
                        T->element = X;
                        T->left = T->right = NULL;
                   }
          }
          else    
               if(X < T->element)
                  T->left = insert(X , T->left);  
          else    
               if(X > T->element)
                  T->right = insert(X , T->right);   
          
          return T;
    }  

     5、delete

    searchTree * delete( elementType X , searchTree * T)
    {
          searchTree * tem;
          tem = (searchTree *) New searchTree;
    if( T == NULL)
              return NULL;
          else    
               if(X < T->element)
                  T->left = delete(X , T->left);  
          else    
               if(X > T->element)
                  T->right = delete(X , T->right); 
          else 
               if(T->left && T->right)
               {
                   tem = findMin(T->right);
                   T->element = tem->element;
    //               tem = delete(tem->element , tem);
    T->right = delete(T->element , T->right); }
    else {
    tem = T;
    if(T->left == NULL) T = T->right; if(T->right == NULL) T = T->left; delete(tem);
    }
    return T; }

     三、AVL树

    定义:每个节点的左子树和右子树的高度最多差1的二叉查找树。(空树的高度定义为-1)

    插入后,只有那些从 插入点根节点 的路径上的节点的平衡可能被改变,所以沿着  插入点   回溯到  根节点的这条路径并更新平衡信息,就可以找到破坏AVL平衡条件的节点。

    (第一个这样的节点 即破坏性节点中最深的节点)。

    破坏平衡性的节点设为a,则a的左右子树高度差为2,新节点插入点:

    1、a的左儿子的左子树(单旋转)

    2、a的左儿子的右子树(双旋转)

    3、a的右儿子的左子树(单旋转)

    4、a的右儿子的右子树(双旋转)

     1、节点声明

    struct avlNode
    {
        elementType    element;
        avlNode        left;
        avlNode        right;
        int            height;
    }

    2、高度信息

    static int height( avlNode *P)
    {
             if( P == NULL)
                 return -1;    //基准情况
             else
                 return max( height(P->left) , height(P->right) ) + 1;
    }

    3、节点插入

    avlTree *insert(elementType X , avlTree *T)
    {
           if(T == NULL)
           {
               T = (avlTree*) New avlTree;
                if(T == NULL)
                   cout << "out of space" << endl;
                else
                {
                     T->element = X;
                     T->left = T->right = NULL;
                }
           }
            else
            if(X < T->element)
            {
                T->left = insert (X , T->left);
                 if(height(T->left) - height(T->right) == 2)
                 {
                       if(X < T->left->element)
                          T = singleRotateWithLeft(T);
                       else
                          T = doubleRotateWithLeft(T);                 
                 }
            }
            else
            if(X > T->element)
            {
                T->right = insert (X , T->right);
                if(height(T->right) - height(T->left) == 2)
                {
                      if(X > T->right->element)
                          T = singleRotateWithRight(T);
                      else
                          T = doubleRotateWithRight(T);                 
                }
            }
            T->height = height(T); //更新高度信息
            return T;
    }

    4、旋转(给出一组单双旋转)

    static avlTree *singleRotateWithLeft(avlTree *T1)
    {
          avlTree *T2;
          T2 = T1->left;  
    
          T1->left = T2->right;
          T2->right = T1;
          T1->height = height(T1); //更新高度信息
          T2->height = height(T2);
          
          return T2;
    }
    static avlTree *doubleRotateWithLeft(avlTree *T1)
    {
          T1->left = singleRotateWithRight(T1->left);
          // 在旋转中已经有返回值,此时不写return亦可
          rerurn singleRotateWithLeft(T1); 
    }

     四、树的遍历(递归)

    中序遍历:左-中-右

    后序遍历:左-右-中(先遍历儿子)

    前序遍历:中-左-右(先遍历祖先)

    中序遍历:

    void printTree(searchTree *T)
    {
           if(T != NULL)
           {
               printTree(T->left);
               cout<< T->element << endl;
               printTree(T->right);
           }
    }
  • 相关阅读:
    5.JavaSE之数据类型详解
    4.JavaSE之标识符
    2.Java程序运行机制
    1.HelloWorld 仪式感
    10.安装开发环境
    【模板】后缀数组
    Luogu P3808 【模板】AC自动机(简单版)
    Luogu P3375 【模板】KMP字符串匹配
    LNSY集训
    Luogu P2580 于是他错误的点名开始了 (Trie树模板)
  • 原文地址:https://www.cnblogs.com/Lunais/p/5568615.html
Copyright © 2020-2023  润新知