平衡二叉树的实现

来源:互联网 发布:主人网络怎么开启 编辑:程序博客网 时间:2024/05/17 01:16
//平衡二叉树 #include <iostream>#include <stdio.h>#include <stdlib.h>using namespace std;typedef int ElementType; typedef struct BinaryNode{    ElementType data;    int height;    unsigned int freq; //此节点保存的数据出现的频率     struct BinaryNode *left,*right;}BinaryNode,*BinaryTree;//求高度 int Height(BinaryTree pNode){    return pNode == NULL ? -1 : pNode->height;}int Max(int a, int b){    return a < b ? b : a;}//LL型左旋void RotateWithLeft(BinaryTree &pNode){     BinaryTree pTemp = pNode->left; //保存节点的左子树     pNode->left = pTemp->right;    pTemp->right = pNode;     //到此树旋转完成,更新树的深度,以pNode,pTemp为节点的树的深度发生了变化;     pNode->height = Max(Height(pNode->left), Height(pNode->right)) + 1;    pTemp->height = Max(Height(pTemp->left), Height(pTemp->right)) + 1;     //pTemp为局部变量,离开作用域,变量就会销毁,因此需要返回根节点,只不过是通过引用的方式罢了;    pNode = pTemp;}//RR型 void RotateWithRight(BinaryTree &pNode){    BinaryTree pTemp = pNode->right; //保存节点的右子树    pNode->right = pTemp->left;    pTemp->left = pNode;     //到此树旋转完成,更新树的深度,以pNode,pTemp为节点的树的深度发生了变化;     pNode->height = Max(Height(pNode->left), Height(pNode->right)) + 1;    pTemp->height = Max(Height(pTemp->left), Height(pTemp->right)) + 1;     //pTemp为局部变量,离开作用域,变量就会销毁,因此需要返回根节点,只不过是通过引用的方式罢了;     pNode = pTemp;}//LR型 void DoubleRotateWithLeft(BinaryTree &pNode){    RotateWithRight(pNode->left);    RotateWithLeft(pNode);} //RL型 void DoubleRotateWithRight(BinaryTree &pNode){    RotateWithLeft(pNode->right);    RotateWithRight(pNode);} //左平衡处理 void LeftBalance(BinaryTree &pNode){    BinaryTree pTemp = pNode->left;    if(Height(pTemp->left) - Height(pTemp->right) == -1)    {         //右子树高于左子树,在右子树插入的         DoubleRotateWithLeft(pNode);//LR     }    else    {        RotateWithLeft(pNode);//LL      } } //右平衡处理 void RightBalance(BinaryTree &pNode){    BinaryTree pTemp = pNode->right;    if(Height(pTemp->right) - Height(pTemp->left) == -1)    {   //左子树比右子树高,说明在左子树插入的        DoubleRotateWithRight(pNode); //RL      }    else    {        RotateWithRight(pNode);  //RR      }}//插入 void AVL_Insert(BinaryTree &pNode, ElementType key){    if(NULL == pNode)    {        pNode = new BinaryNode;        pNode->data = key;        pNode->height = 0;        pNode->freq= 1;        pNode->left = NULL;        pNode->right = NULL;        }     else if(key < pNode->data) //在左子树插入    {        AVL_Insert(pNode->left, key);        //判断是否破坏AVL树的平衡性        if((Height(pNode->left) - Height(pNode->right)) == 2)        {            LeftBalance(pNode);//左平衡处理          }    }    else if(key > pNode->data) //在右子树插入    {        AVL_Insert(pNode->right, key);        //判断是否破坏AVL树的平衡性        if((Height(pNode->right) - Height(pNode->left)) == 2)        {            RightBalance(pNode); //右平衡处理          }    }    else    {        pNode->freq++;    }    pNode->height = Max(Height(pNode->left), Height(pNode->right)) + 1; //更新树的高度}//查找 BinaryTree AVL_Search(BinaryTree &pNode, ElementType key){    if(pNode == NULL)    {        return NULL;    }    else if(key > pNode->data)     {        AVL_Search(pNode->right, key);    }    else if(key < pNode->data)    {        AVL_Search(pNode->left, key);    }    else    {        return pNode;    }}//删除void AVL_Delete(BinaryTree &pNode, ElementType key) {    if(pNode == NULL) //空树返回     {        return ;     }    if(key < pNode->data) //在左子树中查找     {        AVL_Delete(pNode->left, key);        if((Height(pNode->right) - Height(pNode->left)) == 2) //左子树删除一个节点,判断是否需要右平衡处理         {            RightBalance(pNode);        }       }    else if(key > pNode->data)    {        AVL_Delete(pNode->right, key);        if((Height(pNode->left) - Height(pNode->right)) == 2) //右子树删除一个节点,判断是否需要左平衡处理         {            LeftBalance(pNode); //左平衡处理          }       }    else //找到要删除的元素节点    {        if(pNode->left == NULL) //左子树为空          {            BinaryTree pTemp = pNode;            pNode = pNode->right; //用右孩子代替此节点             free(pTemp);  //释放内存         }        else if(pNode->right == NULL) //右子树为空          {            BinaryTree pTemp = pNode;            pNode = pNode->left; //用左孩子代替此节点             free(pTemp);  //释放内存                    }        else //左右子树都不为空         {            //一般的删除策略是左子树的最小数据 或 右子树的最小数据 代替该节点            BinaryTree pTemp = pNode->left;            while(pTemp->right != NULL)            {                pTemp = pTemp->right;            }            pNode->data = pTemp->data;            AVL_Delete(pNode->left,pTemp->data);        }    }    if(pNode)    {        pNode->height = Max(Height(pNode->left), Height(pNode->right));    }}//中序遍历void AVL_InorderPrint(BinaryTree &pRoot){    if(pRoot != NULL)    {        AVL_InorderPrint(pRoot->left);        cout << pRoot->data << " ";        AVL_InorderPrint(pRoot->right);    }   } int main(){    BinaryTree root = NULL;    AVL_Insert(root,3);    AVL_Insert(root,2);      AVL_Insert(root,1);      AVL_Insert(root,4);      AVL_Insert(root,5);      AVL_Insert(root,6);      AVL_Insert(root,7);      AVL_Insert(root,16);      AVL_Insert(root,15);      AVL_Insert(root,14);     AVL_Insert(root,13);    AVL_Insert(root,12);      AVL_Insert(root,11);      AVL_Insert(root,10);     AVL_Insert(root,8);    AVL_Insert(root,9);    AVL_InorderPrint(root);    printf("\n%d\n",root->height);    AVL_Delete(root,8);     // AVL_Delete(root,5);    AVL_InorderPrint(root);    BinaryTree k = AVL_Search(root,15);      if (k == NULL)      {          printf("没有查找到15\n");      }      else      {          printf("所在节点的高度:%d\n",k->height);          if (NULL!=k->left)          {              printf("所在节点的左孩子:%d\n",k->left->data);          }          if (NULL!=k->right)          {              printf("所在节点的右孩子:%d\n",k->right->data);          }      }    system("pause");    return 0;}