`
Coco_young
  • 浏览: 125310 次
  • 性别: Icon_minigender_1
  • 来自: 湖南长沙
社区版块
存档分类
最新评论

AVL实现

阅读更多
一. AVL概念:
    对于一颗BST,其中每个节点的左右子树高度差均不超过1的平衡二叉搜索树,就叫做AVL树。
二. 如何维护一颗AVL树。
    旋转操作:
    1. rotateWithLeft:(右旋转)
*       (N)                (L)
*      /   \              /   \
*    (L)    3    ==>     1    (N) 
*   /   \                    /   \
*  1     2                  2     3
    2. rotateWithRight:(左旋转)
*    (N)                (R)
*   /   \              /   \
*  1    (R)    ==>   (N)    3
*      /   \        /   \
*     2     3      1     2

三.AVL的基本操作:
   Find(x,AVL);//在AVL树中查找值为X的元素
   Insert(x,&AVL);//在AVL树中插入值为X的元素
   Remove(x,&AVL);//在AVL树中删除值为X的元素
   FindMax(AVL);//查找AVL树中的最大值
   FindMin(AVL);//查找AVL树中的最小值
   rotateWithLeft(&node);//右旋
   rotateWithRight(&node)//左旋


四.AVL的静态实现:
  1.用到的数据结构:int left[],right[],next[],height[],data[].
  2.说明: left,right分别保存节点的左子结点和右子结点,0表示空,height保存某一结点的   高度,用来计算平衡因子,data保存结点的数据.
  3.实现分析:
    (1).FindMax,Find,FindMin,和BST的一样。
    (2).Insert,将元素插入AVL树后,沿插入路径逆向,从插入位置开始,遇到第一个不平 衡的结点就将该子树旋转至平衡,如此操作,整棵AVL都达到平衡。
    (3).Remove,先仿造BST的删除方式进行删除,从删除位置沿删除路径返回根节点,只要遇到不平衡的结点就旋转.
    (4).旋转操作,不平衡的点一定有孙子,祖父与孙子共线: 单旋转;祖父与孙子不共线: 双旋转。(图来自刘汝佳的书《高级数据结构》)
     单旋转:

     双旋转:


五.实现代码:
  
   #include<iostream>
#include<queue>
#include<vector>
using namespace std;
#define SIZE 100
#define MAX(a,b) a>b?a:b
/**
** author: yfr
** date: 2012-1-9
** project: AVL tree
** reference: LRJ's BOOK
** 用数组模拟链式结构(姑且用静态这个说法),实现AVL的插入操作 
** 这里不直接用平衡因子,而是保持树各结点的高度,然后去计算平衡因子 
** 空树的高度是-1 
**/
int Left[SIZE],Right[SIZE],next[SIZE],data[SIZE],height[SIZE];
/*辅助容器*/
vector<int> look[SIZE];
int depth[SIZE];
/**/
/**
所有操作申明 
**/
void Init();
int makenode(int x);
void delnode(int);
int find(int x,int p);
int findmin(int);
int findmax(int);
void insert(int x,int &p);
void remove(int x,int &p);

//初始化各数组
void Init()
{
   memset(Left,0,sizeof(Left));
   memset(Right,0,sizeof(Right));
   memset(height,-1,sizeof(height));//空树高度为-1 
   for(int i=0;i<SIZE;i++)
   next[i] = i+1;
}
//模拟内存分配函数  
int makenode(int x)
{
    int p = next[0];
    next[0] = next[p];
    data[p] = x;
    return p;
}
void delnode(int p)
{
    Left[p] = Right[p] = 0;
    height[p] = -1;
    next[p] = next[0];
    next[0] = p;
}
//AVL的操作函数
/*旋转
         a                           b
          \                         / \
           b    ------------>      a   c
          / \                     /
         d   c                   d 
*/
void rotateWithRight(int &p)
{
     int q = Right[p];
     Right[p] = Left[q];
     Left[q] = p;
     height[p] = MAX(height[Left[p]],height[Right[p]])+1;
     height[q] = MAX(height[Right[q]],height[p])+1;
     p = q;//
} 
/*旋转
         a                           b
        /                           / \
       b      ------------->       c   a
      / \                             /
     c   d                           d  
*/
void rotateWithLeft(int &p)
{
    int q = Left[p];
    Left[p] = Right[q];
    Right[q] = p;
    height[p] = MAX(height[Left[p]],height[Right[p]])+1;
    height[q] = MAX(height[Left[q]],height[p])+1;
    p = q;
}
void insert(int x,int &p)
{
    if(!p)
    {
       p = makenode(x);
       height[p] = MAX(height[Left[p]],height[Right[p]])+1;
       return;
    }
    if(x < data[p])
    {
       insert(x,Left[p]);
       height[p] = MAX(height[Left[p]],height[Right[p]])+1;
       if(height[Left[p]]-height[Right[p]]==2)//不平衡 
       {
           if(height[Left[Left[p]]]-height[Right[Left[p]]]==1)//LL
           {
               rotateWithLeft(p);
           }
           else if(height[Left[Left[p]]]-height[Right[Left[p]]]==-1)//LR
           {
               rotateWithRight(Left[p]);
               rotateWithLeft(p);
           }
       }
    }
    else 
    {
       insert(x,Right[p]);
       height[p] = MAX(height[Left[p]],height[Right[p]])+1;
       if(height[Left[p]]-height[Right[p]]==-2)//不平衡
       {
           if(height[Left[Right[p]]]-height[Right[Right[p]]]==1)//RL
           {
               rotateWithLeft(Right[p]);
               rotateWithRight(p);
           }
           else if(height[Left[Right[p]]]-height[Right[Right[p]]]==-1)//RR
           {
               rotateWithRight(p);
           }
       } 
    }
}
//从AVL树中删除节点 
//先删除,再调整树形 
void remove(int x,int &p)
{
     if(!p) return;//如果是空树,返回
     if(x < data[p]){
          remove(x,Left[p]);
     }
     else if(x > data[p]){
          remove(x,Right[p]);
     }
     else//如果已经找到该结点 
     {
         if(Left[p]&&Right[p])//如果左右结点非空
         {
             int q = findmin(Right[p]);
             data[p] = data[q];
             remove(data[p],Right[p]);
         }
         else
         {
             int q = p;
             p = Left[p]?Right[p]:Left[p]; 
             delnode(q);//释放该结点 
             return;//删除处的高度不需要调整 
         } 
     } 
     if(p){//如果不是空树的话 
       height[p] = MAX(height[Left[p]],height[Right[p]])+1;//记录高度
       //不平衡则旋转 
       if(height[Left[p]]-height[Right[p]]==2)//L
       {
          if(height[Left[Left[p]]]-height[Right[Left[p]]]>=0)//L
          {
             rotateWithLeft(p);//LL旋转 
          }
          else//R 
          {
          //LR旋转 
             rotateWithRight(Left[p]);
             rotateWithLeft(p);
          }
       }
       else if(height[Left[p]]-height[Right[p]]==-2)//R
       {
          if(height[Left[Right[p]]]-height[Right[Right[p]]]<=0)//RR
          {
             rotateWithRight(p);
          }
          else
          {
             //RL
             rotateWithLeft(Right[p]);
             rotateWithRight(p);    
          }
       } 
     }
}
int find(int x,int p)
{
    if(!p)return 0;
    if(x == data[p]) return p;
    if(x < data[p]) return find(x,Left[p]);
    if(x > data[p]) return find(x,Right[p]);
}
int findmin(int p)
{
    if(!p)return 0;//空树
    if(!Left[p]) return p;
    else return findmin(Left[p]); 
}
int findmax(int p)
{
    if(p)
    while(Right[p]) p = Right[p];
    return p;
}
/*********************
辅助函数 
**********************/
//标记好各结点的层数,查看树形时要用到 
void dfs(int p,int deep)
{
   if(!p)return;
   depth[p] = deep;
   dfs(Left[p],deep+1);
   dfs(Right[p],deep+1);
}
void order(int p)
{
   if(!p)return;
   order(Left[p]);
   cout<<data[p]<<endl;
   order(Right[p]);
}
//查看树形 
void bfs(int p)
{
   dfs(p,0);
   queue<int> q;
   q.push(p);
   while(!q.empty())
   {
      int v = q.front();
      q.pop();
      if(Left[v])q.push(Left[v]);
      if(Right[v])q.push(Right[v]);
      cout<<data[v]<<endl;
      look[depth[v]].push_back(data[v]);
   }
}
void print_tree(int deep)
{
     for(int i=0;i<=deep;i++)
     {
        for(int j=0;j<look[i].size();j++)
        {
           cout<<look[i][j];
           for(int k=0;k<=deep-i;k++)
           cout<<" ";
        }
        cout<<endl;
     }
}
int main()
{
    freopen("dataout.txt","w",stdout);
    Init();
    int ROOT = 0;
    insert(10,ROOT);//build AVLtree
    insert(11,ROOT);
    insert(12,ROOT);
    insert(13,ROOT);
    insert(14,ROOT);
    remove(10,ROOT);
    bfs(ROOT);
    print_tree(height[ROOT]);
    return 0;
}

   

  • 大小: 80.4 KB
  • 大小: 62.4 KB
0
0
分享到:
评论

相关推荐

    avl树实现hash表

    在本项目中,我们将讨论如何结合这两种数据结构,利用avl树实现哈希表,以达到更好的性能效果。 首先,让我们了解一下avl树。avl树是一种自平衡二叉搜索树(BST),它的特点是任何节点的两个子树的高度最大差别不...

    AVL树的C++实现

    AVL树是一种自平衡的...总结来说,AVL树的C++实现是一个包含节点类、树类和相关操作实现的过程。通过理解和实现这个过程,你可以深入理解自平衡二叉搜索树的工作原理,并能够灵活地在自己的项目中应用这些数据结构。

    AVL树的C语言实现

    在C语言中实现AVL树,首先需要定义AVL树的节点结构。每个节点包含三个部分:存储数据的关键字(key)、节点的高度(height)以及指向左子树和右子树的指针。一个简单的节点定义如下: ```c typedef struct AVLNode ...

    数据结构avl树实现

    AVL树是一种自平衡二叉查找树(Self-Balancing Binary Search Tree),由G. M. Adelson-Velsky和E. M. Landis在1962年提出,因此得名AVL树,它是最早的自平衡二叉查找树之一。在AVL树中,任意节点的两个子树的高度差...

    AVL树的实现

    基于C++的AVL树实现,

    avltree的简单实现

    一个avltree的简单实现,便于了解avltree的结构及应用

    AVL树C++实现

    学习AVL树的算法实现,使用c++在vc6.0中进行相应的算法实现,对正在学习算法的孩子有帮助

    AVL树的实现基于C++语言

    在C++中实现AVL树,我们需要关注以下几个关键点: 1. **节点结构**:AVL树中的每个节点包含一个键值、指向左子树和右子树的指针,以及表示该节点平衡因子的整数值。平衡因子是节点的左子树高度减去右子树高度。典型...

    AVLTree的实现与分析

    本设计实现了AVLTree的所有的实现功能,也包括BinSTree与AVLTree的转换

    AVL树实现的映射

    AVL树是一种自平衡二叉查找树(Binary Search Tree,BST),由Georgy Adelson-Velsky和Emanuel Land...相比于标准库中的红黑树实现,AVL树在保持平衡方面更严格,可能在某些操作上表现得更快,但实现和维护也更为复杂。

    AVL树C#实现代码

    7. **调试和测试**:在C#2005中,确保AVL树的实现正确性至关重要,可以通过插入一系列已知的数据,然后进行查找、插入和删除操作,检查结果是否符合预期。同时,调试过程中应关注旋转逻辑,确保每次操作后树依然保持...

    AVL树 C++ 实现

    在C++中实现AVL树,我们通常会使用模板类来实现泛型编程,这样可以使得AVL树能够处理不同类型的元素。以下是一个基本的AVL树节点定义: ```cpp template struct AVLNode { T data; int height; AVLNode* left; ...

    AVL树C实现代码

    在C语言中实现AVL树,我们需要关注以下几个关键点: 1. **数据结构定义**:首先,我们需要定义一个结构体来表示AVL树的节点。这个结构体通常包含元素值、节点高度、左子树指针、右子树指针以及平衡因子(左子树高度...

    AVLTree实现的源代码

    在给定的代码中,主要展示了AVL树的插入操作的实现。 首先,我们看到`avlInsert`函数用于在AVL树中插入一个新节点。这个函数首先检查树是否为空,如果为空,则直接创建一个新节点作为树的根节点。接着,通过循环...

    C# 实现AVL树

    在C#中实现AVL树,首先需要理解二叉查找树的基本概念和操作。二叉查找树是一种特殊的二叉树,其中每个节点都包含一个键(key)、一个关联的值、一个指向左子树的指针和一个指向右子树的指针。在二叉查找树中,每个...

    C++ AVL树的实现

    AVL树是一种自平衡二叉查找树(Binary Search Tree,...以上是C++实现AVL树的基础知识点,具体实现过程会涉及更多细节,如旋转的具体代码实现、错误处理等。在实际编码时,还需要注意C++语法和面向对象设计原则的运用。

    C++实现二叉树、搜索二叉树、AVL树

    本话题主要探讨了C++实现的二叉树、二叉搜索树以及AVL树,这些都是高级数据结构,对于优化算法和提高程序效率至关重要。 二叉树是一种特殊的树结构,每个节点最多只有两个子节点,通常分为左子节点和右子节点。在...

    avl树的实现

    在`avl_tree`这个文件中,很可能包含了AVL树的C++、Java或Python等编程语言的实现,包括节点定义、插入、删除和以括号表示法输出等功能。通过阅读和理解这些代码,你可以深入学习AVL树的工作原理和实际应用。

Global site tag (gtag.js) - Google Analytics