二叉树-二叉查找树-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);
       }
}

 

    原文作者:Lunais
    原文地址: https://www.cnblogs.com/Lunais/p/5568615.html
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞