平衡二叉树

平衡二叉树定义(AVL):它或者是一颗空树,或者具有以下性质的二叉树:它的左子树和右子树的深度之差的绝对值不超过1,且它的左子树和右子树都是一颗平衡二叉树。

平衡因子(bf):结点的左子树的深度减去右子树的深度,那么显然-1<=bf<=1;

很显然,平衡二叉树是在二叉排序树(BST)上引入的,就是为了解决二叉排序树的不平衡性导致时间复杂度大大下降,那么AVL就保持住了(BST)的最好时间复杂度O(logn),所以每次的插入和删除都要确保二叉树的平衡

 

变换规则:

 

 

 

插入实例:

 {4, 5 ,7, 2, 1, 3, 6}

 

 

实现代码:

#include <stdio.h>
#include <stdlib.h>

typedef struct avl_tree
{
    int              data;     /*存储数据*/
    int              height;   /*树的深度*/
    struct avl_tree* ltree;    /*指向左子树*/
    struct avl_tree* rtree;    /*指向右子树*/
}avl_tree_s;

static inline int min(int a, int b)
{
    return (a < b ? a : b);
}

static inline int max(int a, int b)
{
    return (a > b ? a : b);
}


/*返回节点的平衡度*/
static inline int height(avl_tree_s* pNode)
{
    if (NULL == pNode)
        return -1;

    return pNode->height;
}

 


/********************************************************************
        pNode                       pNode->ltree
         /                               \
     pNode->ltree     =>               pNode  
         \                               /          
  pNode->ltree->rtree           pNode->ltree->rtree        
 *********************************************************************/
static avl_tree_s* _rotate_single_left(avl_tree_s* pNode)
{
    avl_tree_s* pNode1;

    pNode1 = pNode->ltree;
    pNode->ltree = pNode1->rtree;
    pNode1->rtree = pNode;

    /*结点的位置变了, 要更新结点的高度值*/
    pNode->height = max(height(pNode->ltree), height(pNode->rtree)) + 1;
    pNode1->height = max(height(pNode1->ltree), pNode->height) + 1;

    return pNode1;
}

/********************************************************************
     pNode                            pNode->rtree
       \                                   /   
  pNode->rtree         ==>               pNode
       /                                   \
  pNode->rtree->ltree               pNode->rtree->ltree
 *********************************************************************/
static avl_tree_s* _rotate_single_right(avl_tree_s* pNode)
{
    avl_tree_s* pNode1;

    pNode1 = pNode->rtree;
    pNode->rtree = pNode1->ltree;
    pNode1->ltree = pNode;

    /*结点的位置变了, 要更新结点的高度值*/
    pNode->height = max(height(pNode->ltree), height(pNode->rtree)) + 1;
    pNode1->height = max(height(pNode1->rtree), pNode->height) + 1;

    return pNode1;
}

static avl_tree_s* _rotate_double_left(avl_tree_s* pNode)
{
    pNode->ltree = _rotate_single_right(pNode->ltree);

    return _rotate_single_left(pNode);
}

static avl_tree_s* _rotate_double_right(avl_tree_s* pNode)
{
    pNode->rtree = _rotate_single_left(pNode->rtree);

    return _rotate_single_right(pNode);
}

/* 递归找到最小值 */ 
avl_tree_s *avl_tree_min(avl_tree_s * p) 

    if(p == NULL)
    {
        return NULL;
    }
    else if(p->ltree == NULL)
    {
        return p; 
    }
    else
    {
        return avl_tree_min(p->ltree); 
    }

/* 递归找到最大值 */ 
avl_tree_s *avl_tree_max(avl_tree_s *p) 

    if(p == NULL)
    {
        return NULL;
    }
    else if(p->rtree == NULL)
    {
        return p; 
    }
    else
    {
        return avl_tree_max(p->rtree); 
    }

avl_tree_s *avl_tree_clear(avl_tree_s *p) 

    if(p != NULL)
    {
        avl_tree_clear(p->ltree); 
        avl_tree_clear(p->rtree); 
        free(p); 
    }
   
    return NULL; 

avl_tree_s* avl_tree_balance(int data, avl_tree_s* p)
{
    if (height(p->ltree) - height(p->rtree) == 2)    /*AVL树不平衡*/
    {
        if (data < p->ltree->data)
        {
            /*插入到了左子树左边, 做单旋转*/
            p = _rotate_single_left(p);
        }
        else
        {
            /*插入到了左子树右边, 做双旋转*/
            p = _rotate_double_left(p);
        }
    }
    else if (height(p->rtree) - height(p->ltree) == 2)    /*AVL树不平衡*/
    {
        if (data > p->rtree->data)
        {
            /*插入到了右子树右边, 做单旋转*/
            p = _rotate_single_right(p);
        }
        else
        {
            /*插入到了右子树左边, 做双旋转*/
            p = _rotate_double_right(p);
        }
    }
    else
    {

    }

    return p;
}

avl_tree_s* avl_tree_insert(int data, avl_tree_s* pNode)
{
    if (NULL == pNode)
    {
        pNode = (avl_tree_s*)malloc(sizeof(avl_tree_s));
        pNode->data   = data;
        pNode->height = 0;
        pNode->ltree  = pNode->rtree = NULL;
    }
    else if (data < pNode->data)    /*插入到左子树中*/
    {
        pNode->ltree = avl_tree_insert(data, pNode->ltree);
        pNode = avl_tree_balance(data, pNode);
    }
    else if (data > pNode->data)    /*插入到右子树中*/
    {
        pNode->rtree = avl_tree_insert(data, pNode->rtree);
        pNode = avl_tree_balance(data, pNode);
    }
    else
    {

    }

    /*取左右子树中最大的深度,然后再加上1就是自己的深度*/
    pNode->height = max(height(pNode->ltree), height(pNode->rtree)) + 1;

    return pNode;
}

avl_tree_s *avl_tree_delete(int data, avl_tree_s *pNode) 

    avl_tree_s * node; 
 
    if(pNode == NULL)
    {
        printf("No found!\n"); 
    }
    else if(data < pNode->data)   /* Go left */
    {
        pNode->ltree = avl_tree_delete(data, pNode->ltree);
        pNode->height = max(height(pNode->ltree), height(pNode->rtree)) + 1;
        pNode = avl_tree_balance(data, pNode);
    }
    else if(data > pNode->data)   /* Go Right */
    {
        pNode->rtree = avl_tree_delete(data, pNode->rtree);
        pNode->height = max(height(pNode->ltree), height(pNode->rtree)) + 1;
        pNode = avl_tree_balance(data, pNode);
    }
    else /* Find node to be deleted */
    {
        if(pNode->ltree && pNode->rtree) /* 2 children */ 
        { 
            /* Replace with smallest in right subtree */
           
            node = avl_tree_min(pNode->rtree); 
            pNode->data = node->data; 
            pNode->rtree = avl_tree_delete(pNode->data, pNode->rtree); 
            pNode->height = max(height(pNode->ltree), height(pNode->rtree)) + 1;
            pNode = avl_tree_balance(data, pNode);
        } 
        else /* One or zero children */ 
        { 
            node = pNode; 
            if(pNode->ltree == NULL) /* Also handles 0 children */ 
            {
                pNode = pNode->rtree; 
            }
            else if(pNode->rtree == NULL)
            {
                pNode = pNode->ltree; 
            }
           
            free(node);
        }
    }
 
    return pNode; 
}


/*中序遍历打印树的所有结点*/
void avl_tree_printf(avl_tree_s* pRoot)
{
    if (NULL == pRoot)
        return;

    avl_tree_printf(pRoot->ltree);
    printf("%d ", pRoot->data);
    avl_tree_printf(pRoot->rtree);
}

avl_tree_s * avl_tree_find(int data, avl_tree_s * pRoot)
{
    if (NULL == pRoot)
    {
        return NULL;
    }

    if(data < pRoot->data)
    {
        return avl_tree_find(data, pRoot->ltree);
    }
    else if(data > pRoot->data)
    {
        return avl_tree_find(data, pRoot->rtree);
    }
    else
    {
        return pRoot;
    }
}

int main(int argc, char * argv[])
{
    int data;
    avl_tree_s* pRoot = NULL;

    srand((unsigned int)time(NULL));

    unsigned int i = 0;
    for(i = 0; i < 10; ++i)
    {
        data = rand()%100;
        printf("%d ", data);
        pRoot = avl_tree_insert(data, pRoot);
    }
   
    printf("\n");

    avl_tree_printf(pRoot);
   
    char buf[10];
   
    while(1)
    {
        printf("\n****************************************");
        printf("\n* +number to insert :");
        printf("\n* -number to delete :");
        printf("\n*       q to quit   :");
        printf("\n****************************************\n");
       
        fgets(buf, sizeof(buf), stdin);

        if(buf[0] == 'q')
        {
            break;
        }
        else if(buf[0] == '+')
        {
            pRoot = avl_tree_insert(atoi(&buf[1]), pRoot);
        }
        else if(buf[0] == '-')
        {
            pRoot = avl_tree_delete(atoi(&buf[1]), pRoot);
        }
        else
        {
            continue;
        }

        avl_tree_printf(pRoot);
    }

    pRoot = avl_tree_clear(pRoot);

    return 0;
}


  
posted @ 2013-04-09 14:09  only_eVonne  阅读(297)  评论(0编辑  收藏  举报