avl树是其每个节点的左子树和右子树的高度最多差1的二叉查找树。当在一棵avl树中插入节点的时候,很可能把avl树的平衡给破坏掉,在不平衡的情况下,可以通过对树做单次旋转或者复杂些的双旋转来处理。具体的旋转方法Google去 O(∩_∩)O,这里就不做详细介绍啦。下面仅给已实现的avl树的代码。
/*====================*/ | AvlTree.h | /*====================*/ #ifndef _AVL_TREE_H_ #define _AVL_TREE_H_ #define ElementType int #define Max(a,b) (a)>(b)?(a):(b) struct AvlNode; typedef struct AvlNode * Position; typedef struct AvlNode * AvlTree; //释放树空间 void ClearTree(AvlTree t); //计算节点的高度 int Height(Position p); //插入节点 AvlTree Insert(ElementType x,AvlTree t); //先序遍历 void Preorder_TreePrint(AvlTree t); //中序遍历 void Inorder_TreePrint(AvlTree t); //后序遍历 void Postorder_TreePrint(AvlTree t); //针对左子树做单旋转 static Position SingleRotateWithLeft(Position k2); //针对右子树做单旋转 static Position SingleRotateWithRight(Position k2); //针对左子树做双旋转 static Position DoubleRotateWithLeft(Position k3); //针对右子树做双旋转 static Position DoubleRotateWithRight(Position k3); #endif //AVL树结构体 struct AvlNode { ElementType Element; AvlTree Left; AvlTree Right; int Height; }; /*====================*/ | AvlTree.c | /*====================*/ #include "AvlTree.h" #include <stdio.h> #include <stdlib.h> //清空树 void ClearTree(AvlTree t) { if(t!=NULL) { ClearTree(t->Left); ClearTree(t->Right); free(t); } } //先序遍历 void Preorder_TreePrint(AvlTree t) { if(t!=NULL) { printf("%d(%d) /n",t->Element,t->Height); Preorder_TreePrint(t->Left); Preorder_TreePrint(t->Right); } } //中序遍历 void Inorder_TreePrint(AvlTree t) { if(t!=NULL) { Inorder_TreePrint(t->Left); printf("%d(%d) /n",t->Element,t->Height); Inorder_TreePrint(t->Right); } } //后续遍历 void Postorder_TreePrint(AvlTree t) { if(t!=NULL) { Postorder_TreePrint(t->Left); Postorder_TreePrint(t->Right); printf("%d(%d) /n",t->Element,t->Height); } } //插入节点 AvlTree Insert(ElementType x,AvlTree t) { if (t == NULL) { t = (AvlTree)malloc(sizeof(struct AvlNode)); if (t == NULL) { printf("out of space!!/n"); } else { t->Element = x; t->Left = NULL; t->Right = NULL; t->Height = 0; } } else if(x < t->Element) { t->Left = Insert(x,t->Left); if (Height(t->Left)-Height(t->Right) == 2) { if (x < t->Left->Element) { t = SingleRotateWithLeft(t); } else { t = DoubleRotateWithLeft(t); } } } else if (x > t->Element) { t->Right = Insert(x,t->Right); if (Height(t->Right)-Height(t->Left) == 2) { if (x > t->Right->Element) { t = SingleRotateWithRight(t); } else { t = DoubleRotateWithRight(t); } } } t->Height = Max(Height(t->Left),Height(t->Right))+1; return t; } //算节点的高度 int Height(Position p) { if(p == NULL) return 0; else return Max(Height(p->Left),Height(p->Right))+1; } //针对左子树做单旋转 static Position SingleRotateWithLeft(Position k2) { Position k1; k1 = k2->Left; k2->Left=k1->Right; k1->Right = k2; k2->Height = Max(Height(k2->Left),Height(k2->Right))+1; k1->Height = Max(Height(k1->Left),Height(k1->Right))+1; return k1; } //针对右子树做单旋转 static Position SingleRotateWithRight(Position k2) { Position k1; k1 = k2->Right; k2->Right = k1->Left; k1->Left = k2; k2->Height = Max(Height(k2->Left),Height(k2->Right))+1; k1->Height = Max(Height(k1->Left),Height(k1->Right))+1; return k1; } //针对左子树做双旋转 static Position DoubleRotateWithLeft(Position k3) { k3->Left = SingleRotateWithRight(k3->Left); return SingleRotateWithLeft(k3); } //针对右子树做双旋转 static Position DoubleRotateWithRight(Position k3) { k3->Right = SingleRotateWithLeft(k3->Right); return SingleRotateWithRight(k3); } /*====================*/ | main.c | /*====================*/ #include "AvlTree.h" #include <stdio.h> int main() { int i = 0; AvlTree at = NULL; for(i=0;i<10;i++) at = Insert(i,at); Preorder_TreePrint(at); ClearTree(at); return 0; }