平衡二叉树
来源:互联网 发布:表单数据 编辑:程序博客网 时间:2024/06/15 18:19
AVL树的简介
AVL树(即平衡二叉树)是自平衡的二分查找树。在AVL树中任何节点的两个子树的高度差值为一。因此,它也是一个棵在二分查找树(BST)且为二分查找树的改进版。
注:AVL树的“AVL”来自于两位前苏联的发明者Georgy Adelson-Velsky 和 Evgenii Landis。
特点
- AVL树以一棵二分查找树(BST)
- 自平衡:每个节点的左右子树高度相差绝对值不超过1
AVL树的实现
// avl树节点的定义typedef struct AvlNode { int key; struct AvlNode *left; struct AvlNode *right; int height;} AvlNode, *PAvlNode, *AvlTree; // avl节点生成方法PAvlNode _makeAvlNode(int key){ PAvlNode pAvlNode = (PAvlNode)malloc(sizeof(AvlNode)); pAvlNode->key = key; pAvlNode->left = pAvlNode->right = NULL; pAvlNode->height = 0; return pAvlNode;}// avl树高度大小比较int Max(int h1, int h2){ return h1 > h2 ? h1 : h2;}
// avl树高度int Height(AvlTree tree) { if (tree) { return tree->height; } return 0;}// LL旋转AvlTree SingleRotateWithLeft(AvlTree tree){ AvlTree t = tree->left; tree->left = t->right; t->right = tree; // 旋转之后,重新设置节点高度,即左子树或右子树高度最大值加1(本节点的高度1) tree->height = Max(Height(tree->left), Height(tree->right)) + 1; t->height = Max(Height(t->left), Height(t->right)) + 1; return t;}// RR旋转AvlTree SingleRotateWithRight(AvlTree tree){ AvlTree t = tree->right; tree->right = t->left; t->left = tree; tree->height = Max(Height(tree->left), Height(tree->right)) + 1; t->height = Max(Height(t->left), Height(t->right)) + 1; return t;}// RL旋转AvlTree DoubleRotateLeft(AvlTree tree){ tree->left = SingleRotateWithRight(tree->left); return SingleRotateWithLeft(tree);}// LR旋转AvlTree DoubleRotateRight(AvlTree tree){ tree->right = SingleRotateWithLeft(tree->right); return SingleRotateWithRight(tree);}// avl树节点插入方法/* [参数] tree : avl树根节点指针 key : 插入avl树的关键字 [返回值] 返回关键字插入位置的指针 */AvlTree Insert(AvlTree tree, int key){ if (tree == NULL) { tree = _makeAvlNode(key); return tree; } else { if (key < tree->key) { tree->left = Insert(tree->left, key); if (Height(tree->left) - Height(tree->right) == 2) { if (key < tree->left->key) tree = SingleRotateWithLeft(tree); else tree = DoubleRotateLeft(tree); } } else if (key > tree->key) { tree->right = Insert(tree->right, key); if (Height(tree->right) - Height(tree->left) == 2) { if (key > tree->right->key) tree = SingleRotateWithRight(tree); else tree = DoubleRotateRight(tree); } } } tree->height = Max(Height(tree->left), Height(tree->right)) + 1; return tree;}// 单节点旋转// 需要判断节点的左右子树是否平衡,不平衡进行旋转操作AvlTree Rotate(AvlTree tree){ if (Height(tree->left) - Height(tree->right) == 2) { if (Height(tree->left->left) >= Height(tree->left->right)) { tree = SingleRotateWithLeft(tree); } else { tree = DoubleRotateLeft(tree); } } if (Height(tree->right) - Height(tree->left) == 2) { if (Height(tree->right->right) >= Height(tree->right->left)) { tree = SingleRotateWithRight(tree); } else { tree = DoubleRotateRight(tree); } } return tree;}// avl树节点删除AvlTree Delete(AvlTree tree, int key){ if (tree == NULL) return NULL; if (tree->key == key) { // 被删除节点的左右子树调整 if (tree->right == NULL) { AvlTree t = tree; tree = tree->left; free(t); } else { AvlTree t = tree->right; while (t->left) t = t->left; tree->key = t->key; tree->right = Delete(tree->right, tree->key); tree->height = Max(Height(tree->left), Height(tree->right)) + 1; } return tree; } else if (key > tree->key) { tree->right = Delete(tree->right, key); } else { tree->left = Delete(tree->left, key); } // 删除节点后,重新设置其父节点的高度 tree->height = Max(Height(tree->left), Height(tree->right)) + 1; // 删除节点后,逐级调整被删除节点的父节点 if (tree->left) tree->left = Rotate(tree->left); if (tree->right) tree->right = Rotate(tree->right); if (tree) tree = Rotate(tree); return tree;}// avl树遍历方法void Traversal(AvlTree tree){ if (tree) { if (tree->left) Traversal(tree->left); printf(" %d", tree->key); if (tree->right) Traversal(tree->right); } return;}
// avl树测试方法int main(){ int a[] = {8, 2, 10, 3, 7, 1, 6}; size_t count = sizeof(a)/sizeof(a[0]); AvlTree tree = NULL; for (size_t i = 0; i < count; i++) { tree = Insert(tree, a[i]); } Traversal(tree); printf("\n"); Delete(tree, 7); Traversal(tree); printf("\n"); return 0;}
AVL树的性能
AVL树的查找、插入和删除在平均和最坏情况下都是O(logn)。
BST、AVL和RBTree
- 二分查找树(BST)比较简单,但是很容易产生不平衡的问题而丧失了二分查找树的优势。
- AVL树规定了左右孩子树的高度差超过1则为不平衡,为了维持平衡,在插入和删除子节点后,必须进行相应的旋转。
- 还有一种著名的红黑树,红黑树放宽了平衡的要求,从而减少了操作的次数。
由此AVL和RBTree都是BST的改进版。
参考
1 AVL树的旋转操作 图解 最详细
2 AVL树
3 平衡二叉树(AVL)实现(3)-删除
4 数据结构 – 二叉树(BST, AVLTree, RBTree, SplayTree)
0 0
- 平衡二叉树平衡法则
- 二叉树--二叉平衡树
- 平衡二叉树的
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉查找树
- 平衡二叉树 详解
- 平衡二叉树
- 平衡二叉树
- AVL 平衡二叉树
- 平衡二叉树
- 平衡二叉树-红黑树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- 平衡二叉树
- Matlab常用的集合运算
- Django 创建第一个项目
- Mobile Service
- Microsoft 开源人工智能系统 Malmo
- 初识Servlet监听器
- 平衡二叉树
- 简单排序:冒泡排序、选择排序、插入排序
- 二进制中1的个数(最精简代码)
- Mysql server zip版安装
- java关键字static
- Android 那些你所不知道的Bitmap对象详解
- 计蒜客 联想专卖店大促销
- struts2 面试题
- codeforces 2A-Winner (map)