赞
踩
前提一定是搜索二叉树,对于根节点的左右子树的高度差不能超过1,并且所有子树都要循序这个要求
如果一个搜索二叉树呈现或接近单支状,它的查找效率很低,很接近链表,因此如果能让它平衡时,查找效率最高
由于节点的位置要受到相互之间值的影响,并且在往平衡二叉树中添加节点或者删除节点前,二叉树本身是平衡的,所以只可能在最后操作的节点附近不满足平衡条件,因此需要在该过程中对该节点进行判断并调整。
因此一棵平衡二叉树因为添加操作导致不平衡的原因,总结就四种:
第一种: x y / \ / \ y t1 z x / \ / \ / \ z t2 t3 t4 t2 t1 / \ t3 t4 以y为轴 右旋转 第二种: x y / \ / \ t1 y x z / \ / \ / \ t2 z t1 t2 t3 t4 / \ t3 t4 以y为轴 左旋转 第三种: x x z / \ / \ / \ y t1 z t1 y x / \ / \ / \ / \ t2 z y t4 t2 t3 t4 t1 / \ / \ t3 t4 t2 t3 先以z为轴左旋转 再以z为轴右旋转 达到平衡 第四种: x x z / \ / \ / \ t1 y t1 z x y / \ / \ / \ / \ z t2 t3 y t1 t3 t4 t2 / \ / \ t3 t4 t4 t2 先以z为轴右旋转 再以z为轴左旋转 达到平衡
待删除的节点是叶子节点,直接删除
待删除节点的左子树或者右子树为空,则使用非空节点替换
待删除节点左右子树非空,则根据左右子树的高度,选择高的一边子树,如果是左子树高,选择左子树中的最大节点赋值给待删除节点,然后再左子树中继续删除该最大节点,相当于继续处理情况1或情况2;如果是右子树高,则在右子树选择最小值节点继续同样处理。
删除后可能导致不平衡,需要重新调整平衡
避免了二叉搜索树呈现单支状,让其能以最佳的效率进行查找操作 O(log2n)
在插入、删除操作时,为了达到平衡需要进行大量的左旋、右旋操作、计算高度,所以此时操作速度慢
因此AVL树适合在数据量大并且数据量比较稳定,没有太多的插入、删除操作,适合大量的查找操作。
- #include <stdio.h>
- #include <stdlib.h>
- #include <stdbool.h>
-
- // 设计二叉树节点结构
- typedef struct TreeNode
- {
- int data;
- struct TreeNode* left;
- struct TreeNode* right;
- }TreeNode;
-
- // 创建节点
- TreeNode* create_tree_node(int data)
- {
- TreeNode* node = malloc(sizeof(TreeNode));
- node->data = data;
- node->left = NULL;
- node->right = NULL;
- return node;
- }
-
- // 求高度
- int high_tree(TreeNode* root)
- {
- if(NULL == root) return 0;
- int lh = high_tree(root->left);
- int rh = high_tree(root->right);
- return lh>rh ? lh+1 : rh+1;
- }
-
- // 计算左右子树高度差
- int def_high(TreeNode* root)
- {
- if(NULL == root) return 0;
- return high_tree(root->left) - high_tree(root->right);
- }
-
- // 左旋转
- TreeNode* left_rotate(TreeNode* x)
- {
- TreeNode* y = x->right;
- TreeNode* t2 = y->left;
-
- y->left = x;
- x->right = t2;
-
- return y;
- }
-
- // 右旋转
- TreeNode* right_rotate(TreeNode* x)
- {
- TreeNode* y = x->left;
- TreeNode* t2 = y->right;
-
- y->right = x;
- x->left = t2;
-
- return y;
- }
-
-
- // 自动调整平衡 并返回调整后的根节点
- TreeNode* auto_balance(TreeNode* x)
- {
- if(NULL == x) return NULL;
-
- int lh = high_tree(x->left);
- int rh = high_tree(x->right);
-
- // 左子树高于右子树 超过1
- if(lh - rh > 1)
- {
- // 情况1
- if(def_high(x->left) >= 0)
- {
- // 右旋转
- x = right_rotate(x);
- }
- // 情况3
- else
- {
- // 左旋转
- x->left = left_rotate(x->left);
- // 右旋转
- x = right_rotate(x);
- }
- }
- // 或者 右高于左 超过1
- else if(rh - lh > 1)
- {
- // 情况2
- if(def_high(x->right) <= 0)
- {
- // 左旋转
- x = left_rotate(x);
- }
- // 情况4
- else
- {
- // 右旋转
- x->right = right_rotate(x->right);
- // 左旋转
- x = left_rotate(x);
- }
- }
- return x;
- }
-
- // 添加 返回添加成功后的根节点
- TreeNode* insert_tree(TreeNode* root,int data)
- {
- if(NULL == root)
- return create_tree_node(data);
-
- // 节点添加到合适的位置中
- if(data < root->data)
- root->left = insert_tree(root->left,data);
- else
- root->right = insert_tree(root->right,data);
-
- // 有可能添加后该位置破坏平衡 需要调整
- root = auto_balance(root);
-
- return root;
- }
-
- // 找最大值
- TreeNode* max_tree_node(TreeNode* root)
- {
- if(NULL == root) return NULL;
- TreeNode* max = root;
- while(max->right) max = max->right;
- return max;
- }
-
- // 找最小值
- TreeNode* min_tree_node(TreeNode* root)
- {
- if(NULL == root) return NULL;
- TreeNode* min = root;
- while(min->left) min = min->left;
- return min;
- }
-
- TreeNode* delete_tree(TreeNode* root,int data)
- {
- if(NULL == root) return NULL;
-
- if(root->data == data)
- {
- // 左右皆空 直接删
- if(NULL == root->left && NULL == root->right)
- {
- free(root);
- return NULL;
- }
-
- // 左空 替换为右子树
- if(NULL == root->left)
- {
- TreeNode* temp = root->right;
- free(root);
- return temp;
- }
- // 右空 替换为左子树
- if(NULL == root->right)
- {
- TreeNode* temp = root->left;
- free(root);
- return temp;
- }
-
- // 左右都非空
- // 左边高
- if(def_high(root) >= 0)
- {
- TreeNode* max = max_tree_node(root->left);
- root->data = max->data;
- root->left = delete_tree(root->left,max->data);
- }
- // 右边高
- else
- {
- TreeNode* min = min_tree_node(root->right);
- root->data = min->data;
- root->right = delete_tree(root->right,min->data);
- }
- // 重新调整平衡
- root = auto_balance(root);
- return root;
- }
-
- if(data < root->data)
- root->left = delete_tree(root->left,data);
- else
- root->right = delete_tree(root->right,data);
-
- // 重新调整平衡
- root = auto_balance(root);
- return root;
- }
-
-
- // 遍历
- void dlr_show(TreeNode* root)
- {
- if(NULL == root) return;
- printf("%d ",root->data);
- dlr_show(root->left);
- dlr_show(root->right);
- }
-
- void ldr_show(TreeNode* root)
- {
- if(NULL == root) return;
- ldr_show(root->left);
- printf("%d ",root->data);
- ldr_show(root->right);
- }
-
- void lrd_show(TreeNode* root)
- {
- if(NULL == root) return;
- lrd_show(root->left);
- lrd_show(root->right);
- printf("%d ",root->data);
- }
-
- int main(int argc,const char* argv[])
- {
- TreeNode* root = NULL;
- for(int i=0; i<10; i++)
- {
- root = insert_tree(root,i+1);
- }
- root = insert_tree(root,20);
- root = delete_tree(root,4);
- dlr_show(root);
- printf("\n");
- ldr_show(root);
- printf("\n");
- lrd_show(root);
- printf("\n");
- }
-
-
-
-
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。