向AVL树插入可以通过如同它是未平衡的二叉查找树一样把给定的值插入树中,接着自底向上向根节点折回,于在插入期间成为不平衡的所有节点上进行旋转来完成
头文件AvlTree.h
#ifndef AVLTREE_H
#define AVLTREE_H
typedef int Element;
typedef struct Node{
Element data;
struct Node *left,*right;
int Height; //节点的高度
}AvlNode,*AvlTree,*Position;
void MakeEmpty(AvlTree &T); //清空平衡二叉搜索树
bool IsEmpty(AvlTree T); //判断树是否为空
bool Find(Element x,AvlTree T); //查找元素
Position FindMin(AvlTree T); //查找最小元素
Position FindMax(AvlTree T); //查找最大元素
AvlTree Insert(Element x,AvlTree &T); //插入元素
Position SingleRotateWithLeft(AvlTree k2); //向左单旋转
Position SingleRotateWithRight(AvlTree k2); //向右单旋转
Position DoubleRotateWithLeft(AvlTree k3); //双旋转
Position DoubleRotateWithRight(AvlTree k3); //双旋转
int MAX(int a,int b);
int Height(Position p); //返回节点的高度
void InOrderTraverse(AvlTree T); //前序遍历树
#endif //AVLTREE_H
实现文件AvlTree.cpp
#include "AvlTree.h"
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
void MakeEmpty(AvlTree &T) //清空树
{
if(T == NULL)
return;
MakeEmpty(T->left);
MakeEmpty(T->right);
free(T);
T = NULL;
}
bool IsEmpty(AvlTree T)
{
return T == NULL ? true : false;
}
bool Find(Element x,AvlTree T)
{
if(T == NULL)
return false;
else if(x < T->data) //如果元素小于当前节点往左继续查找
return Find(x,T->left);
else if(x > T->data) //如果元素大于当前节点往右继续查找
return Find(x,T->right);
return true;
}
Position FindMin(AvlTree T) //查找最小值
{
if(T == NULL)
return NULL;
else if(T->left == NULL) //节点的左子树为NULL,此节点就是最小元素的节点
return T;
else
FindMin(T->left);
}
Position FindMax(AvlTree T)
{
if(T == NULL)
return NULL;
else if(T->right == NULL) //节点的右子树为NULL,此节点就是最大元素的节点
return T;
else
FindMax(T->right);
}
AvlTree Insert(Element x,AvlTree &T)
{
if(T == NULL) //创建节点
{
T = (AvlTree)malloc(sizeof(AvlNode));
if(T == NULL)
{
printf("内存分配失败,程序即将退出\n");
exit(1);
}
T->data = x;
T->Height = 0;
T->left = T->right = NULL;
}
else if(x < T->data) //元素小于当前节点的元素,往左继续
{
T->left = Insert(x,T->left);
if(Height(T->left) - Height(T->right) == 2) //如果左边节点的高度比右边节点的高度大2
if(x < T->left->data) //且元素x小于左边的元素,也就是x插入的方向是左边
T = SingleRotateWithLeft(T); //执行单旋转
else
T = DoubleRotateWithLeft(T); //执行双旋转
}
else if(x > T->data)
{
T->right = Insert(x,T->right);
if(Height(T->right) - Height(T->left) == 2)
if(x > T->right->data)
T = SingleRotateWithRight(T);
else
T = DoubleRotateWithRight(T);
}
T->Height = MAX(Height(T->left),Height(T->right)) + 1; //计算在节点插入后的各节点的高度
return T;
}
Position SingleRotateWithLeft(AvlTree k2) //单旋转
{
Position 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),k2->Height) + 1;
return k1;
}
Position SingleRotateWithRight(AvlTree k2)
{
Position 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->right),k2->Height);
return k1;
}
Position DoubleRotateWithLeft(AvlTree k3) //双旋转
{
k3->left = SingleRotateWithRight(k3->left);
return SingleRotateWithLeft(k3);
}
Position DoubleRotateWithRight(AvlTree k3)
{
k3->right = SingleRotateWithLeft(k3->right);
return SingleRotateWithRight(k3);
}
int Height(Position p)
{
return p == NULL ? -1 : p->Height;
}
int MAX(int a,int b)
{
return a > b ? a : b;
}
void InOrderTraverse(AvlTree T) //前序遍历
{
if(T)
{
printf("%d ",T->data);
InOrderTraverse(T->left);
InOrderTraverse(T->right);
}
}
测试文件main.cpp
#include "AvlTree.h"
#include <stdio.h>
int main()
{
AvlTree T = NULL;
int it;
printf("请输入平衡二叉搜索树的数据\n");
while(scanf("%d",&it) != EOF)
Insert(it,T);
printf("平衡二叉搜索树的数据为:\n");
InOrderTraverse(T);
printf("\n");
printf("平衡二叉搜索树的最小元素为:%d\n",FindMin(T)->data);
printf("平衡二叉搜索树的最大元素为:%d\n",FindMax(T)->data);
printf("请输入要查找的内容\n");
scanf("%d",&it);
if(Find(it,T))
printf("在平衡二叉搜索树中找到元素%d\n",it);
else
printf("在平衡二叉搜索树中未找到元素%d\n",it);
MakeEmpty(T);
if(IsEmpty(T))
printf("平衡二叉搜索树为空\n");
return 0;
}