平衡二叉树

来源:互联网 发布:北航软件工程硕士 编辑:程序博客网 时间:2024/06/11 18:44

为什么需要平衡二叉树?不平衡的二叉排序树的查找效率是非常低的,不平衡的最坏情况就是斜树,查找的时间复杂度是O(n),等同于顺序查找。因此我们在构建时就让这棵二叉排序树是平衡二叉树,此时的查找时间复杂度是O(logn),插入和删除也为O(logn),这显然是一种比较理想的动态查找表算法。


平衡二叉树:是一种二叉排序树,其中每一个节点的左子树和右子树的高度差至多等于1。它是一种高度平衡的二叉树。

平衡因子:将二叉树上结点的左子树深度减去右子树深度的值称为平衡因子BF(Balance Factor)。

最小不平衡子树:距离插入结点最近,且平衡因子的绝对值大于1的结点为根的子树,我们称为最小不平衡子树。


平衡二叉树构建的基本思想就是在构建二叉排序树的过程中,每当插入一个结点时,先检查是否因插入而破坏了树的平衡性,若是,则找出最小不平衡子树。在保持二叉排序树特性的前提下,调整最小不平衡子树中各结点之间的链接关系,进行相应的旋转,使之成为新的平衡子树。

1、当最小不平衡子树根结点的平衡因子BF是大于1时,就右旋;小于-1时就左旋。

2、插入结点后,最小不平衡子树的BF与它的子树的BF符合相反时,就需要对结点先进行一次旋转使得符号相同后,再反向旋转一次才能够完成平衡操作。


#define EH 0#define LH +1#define RH -1typedef struct BiTNode{int data;int bf;struct BiTNode *lchild, *rchild;}BiTNode, *BiTree;void R_Rotate(BiTree *P){BiTree L;L = (*P)->lchild;(*P)->lchild = L->rchild;L->rchild = (*P);*P = L;}void L_Rotate(BiTree *P){BiTree R;R = (*P)->rchild;(*P)->rchild = R->lchild;R->lchild = (*P);*P = R;}void LeftBalance(BiTree *T){BiTree L, Lr;L = (*T)->lchild;switch (L->bf){case LH:R_Rotate(T);(*T)->bf = L->bf = EH;break;case RH:Lr = L->rchild;switch (Lr->bf){case LH:(*T)->bf = RH;L->bf = EH;break;case EH:L->bf = (*T)->bf = EH;break;case RH:L->bf = LH;(*T)->bf = EH;break;}Lr->bf = EH;L_Rotate(&(*T)->lchild);R_Rotate(T);}}void RightBalance(BiTree *T){BiTree R, Rl;R = (*T)->rchild;switch(R->bf){case RH:(*T)->bf = R->bf = EH;L_Rotate(T);break;case LH:Rl = R->lchild;switch(Rl->bf){case LH:(*T)->bf = EH;R->bf = RH;break;case EH:(*T)->bf = R->bf = EH;break;case RH:(*T)->bf = LH;R->bf = EH;break;}Rl->bf = EH;R_Rotate((*T)->rchild);L_Rotate(T)}}Status InsertAVL(BiTree *T, int e, Status *taller){if (!*T){*T = (BiTree)malloc(sizeof(BiTNode));(*T)->data = e;(*T)->lchild = (*T)->rchild = NULL;(*T)->bf = EH;*taller = TRUE;}else{if ((*T)->data == e){taller = FALSE;return FALSE;}if ((*T)->data > e){if (!InsertAVL(&(*T)->lchild, e, taller))return FALSE;if (*taller){switch((*T)->bf){case LH:LeftBalance(T);taller = FALSE;break;case EH:(*T)->bf = LH;taller = TRUE;break;case RH:(*T)->bf = EH;taller = FALSE;break;}}}else ((*T)->data < e){if (!InsertAVL(&(*T)->rchild), e, taller)return FALSE;if (*taller){switch((*T)->bf){case LH:(*T)->bf = EH;taller = FALSE;break;case EH:(*T)->bf = RH;taller = TRUE;break;case RH:RightBalance(T);taller = FALSE;break;}}}}return TRUE;} void main() { int i; int a[10] = {3, 2, 1, 4, 5, 6, 7, 10, 9, 8}; Status taller; BiTree T = NULL; for (i = 0; i < a.10; a++) { InsertAVL(&T, a[i], &taller); } }

0 0
原创粉丝点击