//平衡二叉树
#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;
}
平衡二叉树的实现
最新推荐文章于 2024-04-06 15:06:05 发布