平衡二叉树(AVLTree)是指带平衡条件的二叉查找树。AVLTree要求每个节点的左子树和右子树的高度之差最多为1。当因为插入或删除操作导致AVLTree不满足该平衡条件时就需要进行调整操作,包括单旋转和双旋转操作。也正是因为需要时刻保持树的平衡条件,从而使得AVLTree的插入和删除操作较为复杂。
以下给出AVLTree的递归实现。
AVLTree.h:
#ifndef _AVLTree_H #define _AVLTree_H struct AvlNode; typedef struct AvlNode* Position; typedef struct AvlNode* AvlTree; typedef int ElementType; AvlTree MakeEmpty(AvlTree& T); Position Find(ElementType X,AvlTree T ); Position FindMin(AvlTree T); Position FindMax(AvlTree T); AvlTree Insert(ElementType X,AvlTree& T); AvlTree Delete(ElementType X,AvlTree T); int GetHeight(Position P);//获取节点的高度 //前序遍历AVLTree void PPrintTree(AvlTree T); //中序遍历AVLTree void MPrintTree(AvlTree T); //后序遍历AVLTree void LPrintTree(AvlTree T); //辅助函数 //单旋转 返回新根节点(按失衡原因分为四种旋转) Position SingleRotateWithLeft(Position K2);//左左 Position SingleRotateWithRight(Position K2);//右右 //双旋转 返回新的根节点 Position DoubleRotateWithLeft(Position k2);//左右 Position DoubleRotateWithRight(Position K2);//右左 int Max(int a,int b); #endif
#include "AVLTree.h" #include <stdio.h> #include <stdlib.h> int Max(int a,int b) { if(a>b) return a; else return b; } struct AvlNode { ElementType Element; AvlTree Left; AvlTree Right; int Heihgt; }; AvlTree MakeEmpty(AvlTree& T) { if(T!=NULL) { T->Left=NULL; T->Right=NULL; // MakeEmpty(T->Left); //MakeEmpty(T->Right); free(T); T=NULL; } return NULL; } int GetHeight(Position P) { if(P==NULL) return -1; else return P->Heihgt; } Position Find(ElementType X,AvlTree T) { if(T==NULL) return NULL; else if(X<T->Element) return Find(X,T->Left); else if(X>T->Element) return Find(X,T->Right); else return T; } Position FindMin(AvlTree T) { if(T==NULL) return NULL; else if(T->Left==NULL) return T; else return FindMin(T->Left); } Position FindMax(AvlTree T) { if(T==NULL) return NULL; else if(T->Right==NULL) return T; else return FindMax(T->Right); } 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->Heihgt=0; T->Left=NULL; T->Right=NULL; } } else if(X<T->Element) { T->Left=Insert(X,T->Left); if(GetHeight(T->Left)-GetHeight(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(GetHeight(T->Right)-GetHeight(T->Left)==2)//需要调整恢复平衡 if(X>T->Right->Element)//右右 T=SingleRotateWithRight(T); else //右左 T=DoubleRotateWithRight(T); } T->Heihgt=Max(GetHeight(T->Left),GetHeight(T->Right))+1; return T; } //该删除函数 只做到了正确删除目标节点功能,但没有处理删除导致的树平衡被破坏的情况 AvlTree Delete(ElementType X,AvlTree T)//返回被删除位置新节点的指针 { Position TemCell; if(T==NULL) printf("Element is not find \n"); else if(X<T->Element) { T->Left=Delete(X,T->Left); } else if(X>T->Element) { T->Right=Delete(X,T->Right); } else//找到目节点 { if(T->Left && T->Right)//有两个儿节点 { TemCell=FindMin(T->Right); T->Element=TemCell->Element; T->Right=Delete(TemCell->Element,T->Right); } else//注:最终被删除的节点为:单子节点或叶节点 { TemCell=T; if(T->Left==NULL) { T=T->Right; } else if(T->Right==NULL) { T=T->Left; } free(TemCell); } } return T; } //前序遍历AVLTree void PPrintTree(AvlTree T) { if(T==NULL) return; printf("%d ",T->Element); PPrintTree(T->Left); PPrintTree(T->Right); } //后序遍历AVLTree void LPrintTree(AvlTree T) { if(T!=NULL) { LPrintTree(T->Left); LPrintTree(T->Right); printf("%d ",T->Element); } } //中序遍历AVLTree void MPrintTree(AvlTree T) { if(T!=NULL) { MPrintTree(T->Left); printf("%d ",T->Element); MPrintTree(T->Right); } } //单旋转 返回新根节点 Position SingleRotateWithLeft(Position K2)//左左 { Position K1; K1=K2->Left; K2->Left=K1->Right; K1->Right=K2; K2->Heihgt=Max(GetHeight(K2->Left),GetHeight(K2->Right))+1; K1->Heihgt=Max(GetHeight(K1->Left),GetHeight(K1->Right))+1; return K1; } Position SingleRotateWithRight(Position K2)//右右 { Position K1; K1=K2->Right; K2->Right=K1->Left; K1->Left=K2; K2->Heihgt=Max(GetHeight(K2->Left),GetHeight(K2->Right))+1; K1->Heihgt=Max(GetHeight(K1->Left),GetHeight(K1->Right))+1; return K1; } //双旋转 返回新的根节点 Position DoubleRotateWithLeft(Position K2)//左右 { K2->Left=SingleRotateWithRight(K2->Left); return SingleRotateWithLeft(K2); } Position DoubleRotateWithRight(Position K2)//右左 { K2->Right=SingleRotateWithLeft(K2->Right); return SingleRotateWithRight(K2); }
原文地址:http://blog.csdn.net/yuyixinye/article/details/44487983