平衡二叉树AVL的基本操作之插入
2014-07-07 20:42
495 查看
平衡二叉树或是一棵空树,或是具有下列性质的二叉排序树:其左子树和右子树都是平衡二叉树,而且左右子树深度之差绝对值不超过1. 由此引出了平衡因子(balance factor)的概念,bf定义为该结点的左子树的深度减去右子树的深度(有些书是右子树深度减去左子树深度,我是按照左子树减去右子树来计算的,下面的代码也是这样定义的),所以平衡二叉树的结点的平衡因子只可能是 -1,0,1 ,某个结点的平衡因子绝对值大于1,该二叉树就不平衡。
平衡二叉树在出现不平衡状态的时候,要进行平衡旋转处理,有四种平衡旋转处理(单向右旋处理,单向左旋处理,双向旋转(先左后右)处理,双向旋转(先右后左)处理),归根到底是两种(单向左旋处理和单向右旋处理)。
下面是四种旋转的示意图:
图1 LL旋转 和 RR旋转
图2 LR旋转
图3 LR旋转和LL旋转
图4 RL旋转
图5 LR旋转
这四种旋转可以归纳为两类:LL旋转和LR旋转可以归为左旋转,RR旋转和RL旋转归为右旋转。
类型定义:
右旋函数:
AVL树的插入函数:
测试结果:
从0到9到插入结果
REF:
1,http://blog.csdn.net/jkay_wong/article/details/6676488
2,数据结构(C语言版) Ellis Horowitz
平衡二叉树在出现不平衡状态的时候,要进行平衡旋转处理,有四种平衡旋转处理(单向右旋处理,单向左旋处理,双向旋转(先左后右)处理,双向旋转(先右后左)处理),归根到底是两种(单向左旋处理和单向右旋处理)。
下面是四种旋转的示意图:
图1 LL旋转 和 RR旋转
图2 LR旋转
图3 LR旋转和LL旋转
图4 RL旋转
图5 LR旋转
这四种旋转可以归纳为两类:LL旋转和LR旋转可以归为左旋转,RR旋转和RL旋转归为右旋转。
类型定义:
typedef struct AVLNode * AVLTree; typedef struct AVLNode{ int data; short int bf; AVLTree lchild,rchild; }AVLNode;左旋函数:
void leftRotate(AVLTree *root,bool *unbalanced) { AVLTree child,gchild;//gchild : grand child child = (*root)->lchild; if (child->bf == 1) { /* LL rotation */ (*root)->lchild = child->rchild; child->rchild = *root; (*root)->bf = 0; (*root) = child; } else { /* LR rotation */ gchild = child->rchild; child->rchild = gchild->lchild; gchild->lchild = child; (*root)->lchild = gchild->rchild; gchild->rchild = *root; switch (gchild->bf) { case 1: (*root)->bf = -1; child->bf = 0; break; case 0: (*root)->bf = child->bf = 0; break; case -1: (*root)->bf = 0; child->bf = 1; } *root = gchild; } (*root)->bf = 0; *unbalanced = false; }
右旋函数:
void rightRotate(AVLTree *root, bool *unbalanced) { AVLTree child,gchild;/*gchild : grand child*/ child = (*root)->rchild; if (child->bf == -1) { /* RR rotation */ (*root)->rchild = child->lchild; child->lchild = *root; (*root)->bf = 0; (*root) = child; } else { /* RL rotation */ gchild = child->lchild; child->lchild = gchild->rchild; gchild->rchild = child; (*root)->rchild = gchild->lchild; gchild->lchild = *root; switch (gchild->bf) { case -1: (*root)->bf = 1; child->bf = 0; break; case 0: (*root)->bf = child->bf = 0; break; case 1: (*root)->bf = 0; child->bf = -1; } *root = gchild; } (*root)->bf = 0; *unbalanced = false; }
AVL树的插入函数:
void AVLInsert(AVLTree *root, int x, bool *unbalanced) { if(*root == NULL){ /* insert into a null tree */ *unbalanced = true; *root = new AVLNode; (*root)->lchild = (*root)->rchild = NULL; (*root)->bf = 0; (*root)->data = x; } else if (x < (*root)->data) { AVLInsert(&((*root)->lchild),x,unbalanced); if (*unbalanced) /* left branch has grown higher */ switch ((*root)->bf) { case -1: (*root)->bf = 0; *unbalanced = false; break; case 0: (*root)->bf = 1; break; case 1: leftRotate(root,unbalanced); } } else if (x > (*root)->data) { AVLInsert(&((*root)->rchild), x, unbalanced); if (*unbalanced) /* right branch has grown higher */ switch ((*root)->bf){ case 1: (*root)->bf = 0; *unbalanced = false; break; case 0: (*root)->bf = -1; break; case -1: rightRotate(root,unbalanced); } } else { *unbalanced = false; cout<<"Node x = "<<x<<" is alreay in the tree."<<endl; } }
测试结果:
从0到9到插入结果
0 ---------------------cut--------------------- 0 \ 1 ---------------------cut--------------------- 1 / \ 0 2 ---------------------cut--------------------- 1 / \ 0 2 \ 3 ---------------------cut--------------------- 1 / \ 0 3 / \ 2 4 ---------------------cut--------------------- 3 / \ 1 4 / \ \ 0 2 5 ---------------------cut--------------------- 3 / \ 1 5 / \ / \ 0 2 4 6 ---------------------cut--------------------- 3 / \ 1 5 / \ / \ 0 2 4 6 \ 7 ---------------------cut--------------------- 3 / \ 1 5 / \ / \ 0 2 4 7 / \ 6 8 ---------------------cut--------------------- 3 / \ 1 7 / \ / \ 0 2 5 8 / \ \ 4 6 9 ---------------------cut---------------------
REF:
1,http://blog.csdn.net/jkay_wong/article/details/6676488
2,数据结构(C语言版) Ellis Horowitz
相关文章推荐
- 平衡二叉树(AVL)的介绍及基本操作
- AVL---平衡二叉树的基本操作
- 平衡二叉树AVL的基本操作之删除
- 平衡二叉树(AVL)的插入操作
- C++ 实现链表的基本操作之一:链表插入
- 平衡二叉树(AVL)的插入和删除详解(上)
- 实现StringGrid的删除,插入,排序行操作(基本操作啦)
- C#操作word的一些基本方法(word打印,插入文件,插入图片,定位页眉页脚,去掉横线)
- 平衡二叉树操作(查询树高、平衡因子、删除节点、插入节点)
- 07单链表的一些基本操作(创建、测量、插入、打印、删除)
- 写给初学数据结构的同学之(循环双链表基本操作,创建,插入,删除,排序)
- C#的基本DB操作之【插入】
- 平衡二叉树(AVL)--查找、删除、插入(Java实现)
- 表的三种基本操作:插入(insert)、删除(delete)、更新(update)
- 线性表的基本操作:新建,插入,删除,查找(C语言版)
- 平衡二叉树(AVL)的插入和删除详解(下)
- 学习笔记——C语言实现单链表的基本操作:创建、输出、插入结点、删除结点、逆序链表
- linq 基本操作(删除、更新、插入)
- 平衡二叉树(AVL树)的基本操作(附有示意图)
- 试用多态实现线性表(队列,串,堆栈),要求具备线性表的基本操作:插入,删除,测长等。