写在前面
最近写东西用到了平衡二叉树,借机钻研学习一下。
概念
- 平衡二叉查找树,也被称为高度平衡树。相比于“二叉查找树”,它的特点为: AVL树中任何结点的两个子树的高度最大差为1。
- AVL 树的查找、插入和删除在平均和最坏情况下都是O(logn)。
- 对AVL树插入或删除操作时,会破坏AVL树的平衡状态。为了将其重新维持平衡,需要对其进行旋转处理。旋转算法很重要!!
AVL树的实现
头文件的定义
义
#ifndef AVLTREE_H_INCLUDED
#define AVLTREE_H_INCLUDED
typedef int elementType;
typedef struct node
{
elementType key;
struct node *left;
struct node *right;
int height;//当前结点深度
} avlnode,*avltree;
int getNode_height(avlnode *node);//获取当前结点的深度
avlnode *create_node(elementType key,avlnode *left,avlnode *right);//创建结点
avlnode * maximun_node(avltree tree);//求树中最大结点
avlnode *minimun_node(avltree tree);//求树中最小结点
avltree avltree_insertNode(avltree tree,elementType key);//向树中插入结点
avltree avltree_deleNode(avltree tree,elementType key);//删除结点
void pre_order_avltree(avltree tree);//前序遍历
void in_order_avltree(avltree tree);//中序遍历
void post_order_avltree(avltree tree);//后序遍历
void print_avltree(avltree tree, elementType key, int direction);//打印树的信息
avlnode *search_node(avltree tree,elementType key);//根据key 的值搜索结点
#endif // AVLTREE_H_INCLUDED
创建结点
avlnode *create_node(elementType key, avlnode *left, avlnode *right)
{
avlnode *node = (avlnode *)malloc(sizeof(avlnode));
if(node == NULL)
{
printf("创建失败");
return NULL;
}
node->key = key;
node->left = left;
node->right = right;
node->height = 0; //初始化高度为 0
return node;
}
获取结点深度
#define HEIGHT(node) ((node == NULL) ? 0 : (((avlnode *)(node))->height))
int getNode_height(valnode *node)
{
return HEIGHT(node);
}
比较大小
#define MAX(a, b) ((a)>(b)?(a):(b))
旋转(重点)
- 失去平衡可以概括为4种状态: LL(左左), LR (左右), RR (右右)和 RL(右左)。 示意图:
- 上图的4颗数都是失去了平衡的AVL树,从左往右的情况依次是:L