AVL树是最先发明的自平衡二叉查找树, 其增删查时间复杂度都是 O(logn), 是一种相当高效的数据结构。当面对需要频繁查找又经常增删这种情景时,AVL树就非常的适用。[ 博客地址:http://blog.csdn.net/thisinnocence ]
代码:
#include <stdlib.h>
#include <stdio.h>
typedef int bool;
#define true 1
#define false 0
typedef int dataType;
typedef struct BiTNode {
dataType data;
int balance; // 平衡因子 = 左子树深度 - 右子树深度,平衡二叉树取:-1, 0, 1
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
/* 右插入,左旋 */
void leftRotate(BiTree *T) {
BiTree rightTree = (*T)->rchild;
(*T)->rchild = rightTree->lchild;
rightTree->lchild = (*T);
(*T) = rightTree;
}
/* 左插入,右旋 */
void rightRotate(BiTree *T) {
BiTree leftTree = (*T)->lchild;
(*T)->lchild = leftTree->rchild;
leftTree->rchild = (*T);
(*T) = leftTree;
}
/* 左子树高,左平衡 */
void leftBalance(BiTree *T) {
BiTree leftTree = (*T)->lchild;
BiTree leftTreeRight = leftTree->rchild;
switch (leftTree->balance) {
case 1: // 左子树平衡因子为 1, (插入左孩子左子树), 单右旋
(*T)->balance = 0;
leftTree->balance = 0;
rightRotate(T);
break;
case -1: //左子树平衡因子为 -1, (插入左孩子右子树), 双旋
switch (leftTreeRight->balance) {
case 1:
(*T)->balance = -1;
leftTree->balance = 0;
break;
case 0:
(*T)->balance = 0;
leftTree->balance = 0;
break;
case -1:
(*T)->balance = 0;
leftTree->balance = 1;
break;
}
leftTreeRight->balance = 0;
leftRotate(&((*T)->lchild));
rightRotate(T);
}
}
/* 右子树高,右平衡 */
void rightBalance(BiTree *T) {
BiTree rightTree = (*T)->rchild;
BiTree rightTreeLeft = rightTree->lchild;
switch (rightTree->balance) {
case -1: //右子树平衡因子为 -1, (插入右孩子右子树), 单左旋
(*T)->balance = 0;
rightTree->balance = 0;
leftRotate(T);
break;
case 1: //右子树平衡因子为 1, (插入右孩子左子树), 双旋
switch (rightTreeLeft->balance) {
case -1:
(*T)->balance = 1;
rightTree->balance = 0;
break;
case 0:
(*T)->balance = 0;
rightTree->balance = 0;
break;
case 1:
(*T)->balance = 0;
rightTree->balance = -1;
break;
}
rightTreeLeft->balance = 0;
rightRotate(&((*T)->rchild));
leftRotate(T);
}
}
/* AVL 树插入, 先定位, 再插入, 然后维持自平衡*/
bool insertAVL(BiTree *T, int elem, bool *taller) {
if (*T == NULL) {
*T = (BiTree) malloc(sizeof(BiTNode));
(*T)->data = elem;
(*T)->balance = 0;
(*T)->lchild = NULL;
(*T)->rchild = NULL;
*taller = true;
return true;
}
if (elem == (*T)->data) {
*taller = false;
return false;
}
// 如果插入元素小于根节点,递推搜索左子树,插入后维持-左平衡
if (elem < (*T)->data) {
if (!insertAVL(&((*T)->lchild), elem, taller))
return false;
if (*taller) {
switch ((*T)->balance) {
case 1:
leftBalance(T);
*taller = false;
break;
case 0:
(*T)->balance = 1;
*taller = true;
break;
case -1:
(*T)->balance = 0;
*taller = false;
break;
}
}
}
// 如果插入元素大于根节点,递推搜索右子树, 插入后维持-右平衡
if (elem > (*T)->data) {
if (!insertAVL(&((*T)->rchild), elem, taller))
return false;
if (*taller) {
switch ((*T)->balance) {
case 1:
(*T)->balance = 0;
*taller = false;
break;
case 0:
(*T)->balance = -1;
*taller = true;
break;
case -1:
rightBalance(T);
*taller = false;
break;
}
}
}
return true;
}
void inOrderTraverse(BiTree T) {
if (T == NULL) return;
inOrderTraverse(T->lchild);
printf("%d ", T->data);
inOrderTraverse(T->rchild);
}
void preOrderTraverse(BiTree T) {
if (T == NULL) return;
printf("%d ", T->data);
preOrderTraverse(T->lchild);
preOrderTraverse(T->rchild);
}
int main() {
int a[10] = {3, 2, 1, 4, 5, 6, 7, 0, 9, 8};
int i;
bool taller;
BiTree T = NULL;
for (i = 0; i < 10; i++) {
insertAVL(&T, a[i], &taller);
}
printf("inOrderTraverse: ");
inOrderTraverse(T);
printf("\npreOrderTraverse: ");
preOrderTraverse(T);
return 0;
}
/* 运行结果如下,由中序和前序遍历,可还原二叉树,验证是否准确
inOrderTraverse: 0 1 2 3 4 5 6 7 8 9
preOrderTraverse: 4 2 1 0 3 6 5 8 7 9
*/
原文:http://blog.csdn.net/thisinnocence/article/details/39272565