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