平衡二叉树
平衡二叉树定义(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;
}