数据结构定义
#define AVL_NODE_CHILE 0
#define AVL_NODE_PARENT 1
//平衡二叉树节点
typedef struct avl_node
{
int key;//关键字
avl_node* left;//左孩子
avl_node* right;//右孩子
int height;//节点高度
}avl_node;
//二叉树本身
typedef struct avl
{
//根节点
avl_node* root;
int size;//节点数目
}avl;
接口设计
//创建一个节点
avl_node* avl_create_node(int key);
//返回节点高度
int avl_height(avl_node* node);
//比较目标值和节点的大小,
//若目标值大,则返回真,反之返回假
int avl_compare_key(int key, avl_node* node);
//返回两个节点的高度较大值
int max(avl_node* x, avl_node* y);
//创建一颗平衡二叉树
avl* avl_create();
//中序遍历二叉树
void avl_inorder_traversal(avl_node* node);
//LL型,需要右转,返回子树新的根
avl_node* avl_rotate_ll(avl_node* node);
//RR型,需要左转
avl_node* avl_rotate_rr(avl_node* node);
//LR型,先右转在左转
avl_node* avl_balance_lr(avl_node* node);
//RL型,先右转在左转
avl_node* avl_balance_rl(avl_node* node);
//搜索节点
avl_node* avl_search_node(avl_node* node, int type, int key);
//插入一个节点
avl* avl_insert_node(avl* avl, int key);
测试代码
int main()
{
avl* avl = avl_create();
int arr[] = { 21,3,5,26,29,50,18,53,8,67,1,78,6 };
//int arr[] = { 21,3,5,26,29,50 };
int length = sizeof(arr) / sizeof(int);
for (int i = 0; i < length; i++)
{
printf("-----------------\n");
printf("插入:%d\n", arr[i]);
avl_insert_node(avl, arr[i]);
printf("中序:");
avl_inorder_traversal(avl->root);
printf("\n");
}
return 0;
}
接口实现
//创建一个节点
avl_node* avl_create_node(int key)
{
avl_node* node = (struct avl_node*)malloc(sizeof(struct avl_node));
if (node == NULL)return NULL;
node->height = 1;
node->key = key;
node->left = NULL;
node->right = NULL;
return node;
}
//返回节点高度
int avl_height(avl_node* node)
{
if (node == NULL)return 0;
return node->height;
}
//比较目标值和节点的大小,
//若目标值大,则返回真,反之返回假
int avl_compare_key(int key, avl_node* node)
{
if (node == NULL)return 0;
if (key > node->key)return 1;
return 0;
}
//返回两个节点的高度较大值
int max(avl_node* x, avl_node* y)
{
int m = avl_height(x);
int n = avl_height(y);
return m > n ? m : n;
}
//创建一颗平衡二叉树
avl* avl_create()
{
avl* avl = (struct avl*)malloc(sizeof(struct avl));
if (avl == NULL)return NULL;
avl->root = NULL;
avl->size = 0;
return avl;
}
//中序遍历二叉树
void avl_inorder_traversal(avl_node* node)
{
if (node != NULL)
{
avl_inorder_traversal(node->left);
printf("%d\t", node->key);
avl_inorder_traversal(node->right);
}
return;
}
//LL型,需要右转,返回子树新的根
avl_node* avl_rotate_ll(avl_node* node)
{
//新的根
avl_node* top = node->left;
node->left = top->right;
top->right = node;
//重新计算节点高度,从低高度节点先计算
node->height = max(node->left, node->right) + 1;
top->height = max(top->left, top->right) + 1;
return top;
}
//RR型,需要左转
avl_node* avl_rotate_rr(avl_node* node)
{
//新的根
avl_node* top = node->right;
node->right = top->left;
top->left = node;
//重新计算节点高度,从低高度节点先计算
node->height = max(node->left, node->right) + 1;
top->height = max(top->left, top->right) + 1;
return top;
}
//LR型,先右转在左转
avl_node* avl_balance_lr(avl_node* node)
{
node->left = avl_rotate_rr(node->left);
return avl_rotate_ll(node);
}
//RL型,先右转在左转
avl_node* avl_balance_rl(avl_node* node)
{
node->right = avl_rotate_ll(node->right);
return avl_rotate_rr(node);
}
//搜索节点
avl_node* avl_search_node(avl_node* node, int type, int key)
{
avl_node* cur = node;
avl_node* parent = NULL;
if (cur == NULL)return NULL;
while (cur != NULL)
{
if (key < cur->key)
{
parent = cur;
cur = cur->left;
}
else if (key == cur->key)
{
break;
}
else if (key > cur->key)
{
parent = cur;
cur = cur->right;
}//end_if
}//end_while
if (type == AVL_NODE_CHILE)return cur;
return parent;
}
//插入一个节点
avl* avl_insert_node(avl* avl, int key)
{
std::stack<avl_node*>stack;
avl_node* cur = avl->root;
avl_node* parent = NULL;
//如果是空树则直接插入
if (cur == NULL)
{
avl->root = avl_create_node(key);
avl->size++;
return avl;
}
//找到待插入节点的位置,通过栈记录路径节点值
while (cur != NULL)
{
stack.push(cur);
if (key < cur->key)
{
parent = cur;
cur = cur->left;
}
else if (key == cur->key)
{
break;
}
else if (key > cur->key)
{
parent = cur;
cur = cur->right;
}
}//end_whhile
//执行到此处parent不可能为空
if (parent == NULL)return NULL;
//插入节点
if (key < parent->key)
parent->left = avl_create_node(key);
else if (key == parent->key)
return NULL;
else
parent->right = avl_create_node(key);
//回溯栈节点,进行平衡调整
while (!stack.empty())
{
cur = stack.top();
stack.pop();
if (stack.empty())
parent = NULL;
else
parent = stack.top() ;
//调整高度
cur->height = max(cur->left, cur->right) + 1;
//计算平衡因子
int bf = avl_height(cur->left) - avl_height(cur->right);
printf("回退:%d,left:%d,right:%d,bf:%d\n", cur->key, avl_height(cur->left), avl_height(cur->right), bf);
//为rr或者rl型
if (bf == -2)
{
//待插入key若比右子树大,则为rr型
if (avl_compare_key(key, cur->right))
{
//该不平衡子树是否右父节点
if (parent == NULL)
avl->root = avl_rotate_rr(cur);
else
{
//有父节点,需要判断该不平衡子树是parent的左子树还是右子树
if (cur->key < parent->key)
parent->left = avl_rotate_rr(cur);
else
parent->right = avl_rotate_rr(cur);
}//end_if
}
//否则为rl型
else
{
if (parent == NULL)
avl_balance_rl(cur);
else
{
if (cur->key < parent->key)
parent->left = avl_balance_rl(cur);
else
parent->right = avl_balance_rl(cur);
}
}//end_if
}
else if (bf == 2)
{
//lr型
if (avl_compare_key(key, cur->left))
{
if(parent==NULL)
avl->root=avl_balance_lr(cur);
else
{
if (cur->key < parent->key)
parent->left = avl_balance_lr(cur);
else
parent->right = avl_balance_lr(cur);
}
}
//ll型
else
{
if (parent == NULL)
avl->root = avl_rotate_ll(cur);
else
{
//有父节点,需要判断该不平衡子树是parent的左子树还是右子树
if (cur->key < parent->key)
parent->left = avl_rotate_ll(cur);
else
parent->right = avl_rotate_ll(cur);
}
}
}//end_if
if (parent != NULL)
parent->height = max(parent->left, parent->right) + 1;
}//end_while
avl->size++;
return avl;
}