平衡二叉树(AVLTree)

来源:互联网 发布:淘宝购物流程步骤图 编辑:程序博客网 时间:2024/05/18 03:52

         平衡二叉树(AVLTree)是指带平衡条件的二叉查找树。AVLTree要求每个节点的左子树和右子树的高度之差最多为1。当因为插入或删除操作导致AVLTree不满足该平衡条件时就需要进行调整操作,包括单旋转和双旋转操作。也正是因为需要时刻保持树的平衡条件,从而使得AVLTree的插入和删除操作较为复杂。

以下给出AVLTree的递归实现。


AVLTree.h:

#ifndef _AVLTree_H#define _AVLTree_Hstruct 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);//获取节点的高度//前序遍历AVLTreevoid PPrintTree(AvlTree T);//中序遍历AVLTreevoid MPrintTree(AvlTree T);//后序遍历AVLTreevoid 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 


AVLTree.cpp:

#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; elsereturn 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;}//前序遍历AVLTreevoid PPrintTree(AvlTree T){if(T==NULL)return;printf("%d ",T->Element);PPrintTree(T->Left);PPrintTree(T->Right);}//后序遍历AVLTreevoid LPrintTree(AvlTree T){ if(T!=NULL) {LPrintTree(T->Left);LPrintTree(T->Right);printf("%d ",T->Element); }}//中序遍历AVLTreevoid 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);}



0 0
原创粉丝点击